From 25ae77d4af61842cfdf51a311858c7e98745513b Mon Sep 17 00:00:00 2001
From: Brian Weaver <weaver.299@osu.edu>
Date: Wed, 6 May 2020 13:34:04 -0400
Subject: [PATCH] SECURITY update: webform 5.11

---
 composer.json                                 |    2 +-
 composer.lock                                 |   38 +-
 vendor/composer/autoload_classmap.php         |    2 -
 vendor/composer/autoload_real.php             |    3 +
 vendor/composer/autoload_static.php           |    2 -
 vendor/composer/installed.json                |   32 +-
 web/modules/webform/composer.json             |    7 +-
 web/modules/webform/composer.libraries.json   |   29 +-
 .../config/install/webform.settings.yml       |    2 +-
 .../install/webform.webform.contact.yml       |    4 +-
 web/modules/webform/css/webform.ajax.css      |    1 +
 .../webform/css/webform.element.scale.css     |  226 +
 .../webform/css/webform.element.table.css     |   58 +
 .../css/webform.element.tableselect.css       |    2 +-
 .../webform/css/webform.theme.seven.css       |    3 +-
 web/modules/webform/docs/RELEASE-NOTES.md     |   47 +-
 web/modules/webform/drush/webform.drush.inc   |   27 +-
 .../images/addons/emfluence_webform.png       |  124 +
 .../images/addons/hn_react_webform.png        |   15 +
 .../images/addons/react_webform_backend.svg   |    8 +
 .../images/addons/webform_calculation.png     |   15 +
 .../webform/images/addons/webform_rest.png    |   55 +
 .../images/addons/webform_sugarcrm.png        |   85 +
 .../images/addons/webform_sugarcrm.svg        |   50 -
 .../includes/webform.install.requirements.inc |    2 +-
 .../includes/webform.install.update.inc       |  192 +
 web/modules/webform/js/webform.block.js       |    2 +-
 .../webform/js/webform.element.codemirror.js  |   11 +-
 .../webform/js/webform.element.date.js        |    4 +-
 .../webform/js/webform.element.inputhide.js   |    2 +-
 .../js/webform.element.location.places.js     |    4 +-
 .../webform/js/webform.element.rating.js      |    3 +
 .../webform/js/webform.element.states.js      |    4 +-
 web/modules/webform/js/webform.filter.js      |    3 +-
 web/modules/webform/js/webform.form.js        |   19 +
 web/modules/webform/js/webform.states.js      |    6 +
 .../src/WebformAccessGroupListBuilder.php     |    1 +
 .../src/WebformAccessTypeListBuilder.php      |    3 +-
 .../webform_access/webform_access.info.yml    |    6 +-
 ...webform.webform.test_attachment_access.yml |    2 +
 .../webform.webform.test_attachment_email.yml |    6 +-
 ...bform.webform.test_attachment_sanitize.yml |    2 +
 ...webform.webform.test_attachment_states.yml |    4 +-
 .../webform.webform.test_attachment_token.yml |    2 +
 .../webform.webform.test_attachment_twig.yml  |    2 +
 .../webform.webform.test_attachment_url.yml   |    2 +
 .../webform_attachment_test.info.yml          |    6 +-
 .../webform_attachment.info.yml               |    6 +-
 .../webform_bootstrap_test_module.info.yml    |    6 +-
 .../webform_bootstrap_test_theme.info.yml     |    6 +-
 .../webform_bootstrap.info.yml                |    6 +-
 .../webform.webform.demo_application.yml      |    3 +
 ...rm.webform.demo_application_evaluation.yml |    7 +-
 ...bform_demo_application_evaluation.info.yml |    6 +-
 ...webform_demo_application_evaluation.module |    2 +-
 ...ebform.webform.demo_event_registration.yml |    4 +-
 .../webform_demo_event_registration.info.yml  |    6 +-
 .../webform.webform.webform_group_contact.yml |   10 +-
 .../webform_demo_group.info.yml               |    6 +-
 .../webform.webform.demo_region_contact.yml   |    4 +-
 .../webform_demo_region_contact.info.yml      |    6 +-
 .../WebformDevelEntityFormApiBaseForm.php     |   23 +-
 .../webform_devel/webform_devel.info.yml      |    6 +-
 .../webform_editorial.info.yml                |    7 +-
 .../webform.webform.test_entity_print.yml     |    2 +
 ...bform.webform.test_entity_print_custom.yml |    2 +
 .../webform_entity_print_test.info.yml        |    6 +-
 .../webform_entity_print.info.yml             |    6 +-
 ...m.webform.test_entity_print_attachment.yml |    4 +-
 ...form_entity_print_attachment_test.info.yml |    6 +-
 .../webform_entity_print_attachment.info.yml  |    6 +-
 ...form.webform.webform_example_composite.yml |    2 +
 .../webform_example_composite.info.yml        |    6 +-
 ...rm.webform.webform_example_custom_form.yml |    4 +-
 .../webform_example_custom_form.info.yml      |    6 +-
 ...ebform.webform.webform_example_element.yml |    2 +
 .../webform_example_element.info.yml          |    6 +-
 ...ebform_example_element_properties.info.yml |    6 +-
 ...ebform.webform.webform_example_handler.yml |    2 +
 .../webform_example_handler.info.yml          |    6 +-
 .../webform.webform.example_remote_post.yml   |   14 +-
 .../webform_example_remote_post.info.yml      |    6 +-
 ...ebform.webform_example_variant_ab_test.yml |    5 +-
 ...bform.webform_example_variant_segments.yml |    2 +
 .../webform_example_variant.info.yml          |    6 +-
 ...form.webform.example_computed_elements.yml |    4 +-
 ...webform.example_computed_elements_ajax.yml |    2 +
 ...webform.webform.example_element_states.yml |    2 +
 ...webform.webform.example_flexbox_layout.yml |    2 +
 .../webform.webform.example_input_masks.yml   |    2 +
 .../webform.webform.example_style_guide.yml   |   88 +-
 .../webform.webform.example_wizard.yml        |    2 +
 .../webform_examples.info.yml                 |    6 +-
 ...webform.example_accessibility_advanced.yml |    2 +
 ...rm.webform.example_accessibility_basic.yml |    2 +
 ...bform.example_accessibility_containers.yml |    2 +
 ...m.webform.example_accessibility_labels.yml |    2 +
 ...m.webform.example_accessibility_wizard.yml |    2 +
 .../webform_examples_accessibility.info.yml   |    6 +-
 ...bform.webform.test_element_group_roles.yml |    4 +
 ...form.webform.test_group_element_access.yml |    4 +
 .../webform_group_test.info.yml               |    6 +-
 .../webform_group/webform_group.info.yml      |    6 +-
 .../webform.webform.test_element_icheck.yml   |    4 +-
 ...orm.webform.test_element_icheck_styles.yml |    4 +-
 .../webform_icheck_test.info.yml              |    6 +-
 .../webform_icheck/webform_icheck.info.yml    |    6 +-
 .../src/Element/WebformImageSelect.php        |    7 +-
 .../src/WebformImageSelectImagesForm.php      |   19 +-
 ...form.webform.test_element_image_select.yml |    2 +
 .../webform.webform.test_element_images.yml   |    2 +
 .../webform_image_select_test.info.yml        |    6 +-
 .../WebformImageSelectElementTest.php         |    2 +-
 .../webform_image_select.info.yml             |    6 +-
 .../webform.webform.test_element_buttons.yml  |    4 +-
 .../webform_jqueryui_buttons_test.info.yml    |    6 +-
 .../webform_jqueryui_buttons.info.yml         |    6 +-
 ...m.webform.test_element_loc_geocomplete.yml |    4 +-
 ...webform_location_geocomplete_test.info.yml |    6 +-
 .../webform_location_geocomplete.info.yml     |    6 +-
 .../src/Access/WebformNodeAccess.php          |   16 +-
 ...m.webform.webform_node_test_multiple_a.yml |    2 +
 ...m.webform.webform_node_test_multiple_b.yml |    2 +
 .../webform_node_test_multiple.info.yml       |    6 +-
 ....webform.webform_node_test_translation.yml |    2 +
 .../webform_node_test_translation.info.yml    |    6 +-
 .../tests/src/Functional/WebformNodeTest.php  |   27 +-
 .../webform_node/webform_node.info.yml        |    6 +-
 .../modules/webform_node/webform_node.module  |    2 +-
 ...webform.webform.example_options_custom.yml |    2 +
 ...ebform.test_element_options_custom_ent.yml |    2 +
 ...ebform_options_custom_entity_test.info.yml |    6 +-
 ...bform.test_element_options_custom_html.yml |    2 +
 ...bform.test_element_options_custom_imap.yml |    2 +
 ...ebform.test_element_options_custom_svg.yml |    2 +
 ...bform.test_element_options_custom_twig.yml |    2 +
 ...m.webform_options_custom.test_ballroom.yml |    4 +-
 .../webform_options_custom_test.info.yml      |    6 +-
 .../webform_options_custom.info.yml           |    6 +-
 .../schema/webform_options_limit.schema.yml   |    3 +
 .../OptionsLimitWebformHandler.php            |  115 +-
 ...orm.webform.test_handler_boolean_limit.yml |    3 +
 ...orm.webform.test_handler_options_limit.yml |   75 +-
 ...webform.test_handler_options_limit_ent.yml |    3 +
 ...ebform.test_handler_options_limit_user.yml |    3 +
 .../webform_options_limit_test.info.yml       |    6 +-
 .../Functional/WebformOptionsLimitTest.php    |   21 +
 .../webform_options_limit.info.yml            |    6 +-
 .../webform_options_limit.install             |    7 +
 ...m.webform.test_handler_scheduled_email.yml |    4 +-
 .../webform_scheduled_email_test.info.yml     |    6 +-
 ...bform.test_handler_scheduled_translate.yml |    4 +-
 ..._scheduled_email_test_translation.info.yml |    6 +-
 .../webform_scheduled_email.info.yml          |    6 +-
 .../webform_shortcuts.info.yml                |    6 +-
 .../webform_shortcuts.libraries.yml           |    2 +-
 .../WebformSubmissionExportImportImporter.php |    2 +-
 ....webform.test_submission_export_import.yml |    2 +
 ...orm_submission_export_import_test.info.yml |    6 +-
 .../webform_submission_export_import.info.yml |    6 +-
 .../webform_submission_log.info.yml           |    6 +-
 .../webform.webform.template_contact.yml      |    4 +-
 ...m.webform.template_employee_evaluation.yml |    2 +
 .../webform.webform.template_feedback.yml     |    4 +-
 .../webform.webform.template_issue.yml        |    2 +
 ...bform.webform.template_job_application.yml |    4 +-
 ...rm.webform.template_job_seeker_profile.yml |    6 +-
 ...m.webform.template_medical_appointment.yml |    4 +-
 .../webform.webform.template_registration.yml |    4 +-
 ...rm.webform.template_session_evaluation.yml |    4 +-
 .../webform.webform.template_subscribe.yml    |    4 +-
 .../webform.webform.template_user_profile.yml |    4 +-
 .../webform_templates.info.yml                |    6 +-
 .../webform.webform.test_element_toggles.yml  |    4 +-
 .../webform_toggles_test.info.yml             |    6 +-
 .../webform_toggles/webform_toggles.info.yml  |    6 +-
 .../webform_ui/css/webform_ui.module.css      |   25 +
 .../src/Form/WebformUiElementFormBase.php     |   86 +-
 .../src/WebformUiEntityElementsForm.php       |   28 +-
 .../modules/webform_ui/webform_ui.info.yml    |    6 +-
 .../src/Commands/WebformCliService.php        |   48 +
 .../webform/src/Commands/WebformCommands.php  |   20 +-
 .../Controller/WebformEntityController.php    |   21 +-
 .../webform/src/Element/WebformActions.php    |   10 +-
 .../webform/src/Element/WebformCodeMirror.php |    5 +-
 .../src/Element/WebformEmailMultiple.php      |    2 +-
 .../webform/src/Element/WebformScale.php      |  122 +
 .../webform/src/Element/WebformSignature.php  |   63 +
 .../Element/WebformSubmissionViewsReplace.php |   22 +-
 .../webform/src/Element/WebformTable.php      |   46 +
 .../webform/src/Element/WebformTableRow.php   |   51 +
 .../src/Element/WebformTermReferenceTrait.php |   14 +
 .../webform/src/Element/WebformVideoFile.php  |    2 +-
 web/modules/webform/src/Entity/Webform.php    |    4 +-
 .../webform/src/Entity/Webform.php.orig       | 3056 ++++++++++++++
 .../webform/src/Entity/WebformSubmission.php  |    5 +-
 .../WebformEntitySettingsGeneralForm.php      |    1 +
 .../WebformAdminConfigElementsForm.php        |    2 +-
 .../webform/src/Form/WebformAjaxFormTrait.php |    6 +
 .../src/Form/WebformResultsExportForm.php     |    6 +-
 .../src/Form/WebformVariantFormBase.php       |    2 +-
 .../WebformEntityReferenceWidgetTrait.php     |   44 +
 .../src/Plugin/WebformElement/NumericBase.php |   18 +
 .../src/Plugin/WebformElement/OptionsBase.php |  125 +-
 .../WebformElement/OptionsBase.php.orig       | 1073 +++++
 .../src/Plugin/WebformElement/Telephone.php   |    2 +-
 .../src/Plugin/WebformElement/TextBase.php    |   13 +-
 .../Plugin/WebformElement/TextBase.php.orig   |  438 ++
 .../WebformElement/WebformCompositeBase.php   |    4 +-
 .../WebformElement/WebformManagedFileBase.php |   14 +
 .../Plugin/WebformElement/WebformScale.php    |  117 +
 .../WebformElement/WebformSignature.php       |   23 +-
 .../Plugin/WebformElement/WebformTable.php    |  272 ++
 .../Plugin/WebformElement/WebformTableRow.php |  420 ++
 .../webform/src/Plugin/WebformElementBase.php |    2 +-
 .../src/Plugin/WebformElementBase.php.orig    | 3700 +++++++++++++++++
 .../RemotePostWebformHandler.php              |   26 +-
 .../Plugin/WebformHandlerPluginCollection.php |    9 +-
 .../Plugin/WebformVariantPluginCollection.php |   11 +-
 .../Routing/WebformUncacheableResponse.php    |   24 +
 .../src/Utility/WebformElementHelper.php      |   56 +-
 .../src/Utility/WebformOptionsHelper.php      |    3 +-
 .../webform/src/WebformAddonsManager.php      |   18 +-
 .../src/WebformEntityElementsValidator.php    |   12 +-
 .../webform/src/WebformEntityListBuilder.php  |    2 +-
 .../webform/src/WebformHelpManager.php        |    6 +
 .../webform/src/WebformLibrariesManager.php   |    4 +-
 .../webform/src/WebformOptionsForm.php        |   19 +-
 .../webform/src/WebformSubmissionForm.php     |  146 +-
 .../src/WebformSubmissionListBuilder.php      |    9 +-
 .../webform/src/WebformSubmissionStorage.php  |   33 +-
 .../src/WebformSubmissionStorageSchema.php    |    4 +
 .../install/webform.webform.test_ajax.yml     |    2 +
 ....webform.test_ajax_confirmation_inline.yml |    2 +
 ...webform.test_ajax_confirmation_message.yml |    2 +
 ...m.webform.test_ajax_confirmation_modal.yml |    2 +
 ...rm.webform.test_ajax_confirmation_page.yml |    2 +
 ...orm.webform.test_ajax_confirmation_url.yml |    2 +
 ...webform.test_ajax_confirmation_url_msg.yml |    2 +
 .../webform.webform.test_composite.yml        |    2 +
 .../webform.webform.test_composite_custom.yml |    2 +
 ...orm.webform.test_composite_custom_file.yml |    2 +
 .../webform.webform.test_composite_format.yml |    4 +-
 ...webform.test_composite_format_multiple.yml |    4 +-
 ...bform.webform.test_confirmation_inline.yml |    2 +
 ...form.webform.test_confirmation_message.yml |    2 +
 ...ebform.webform.test_confirmation_modal.yml |    2 +
 ...webform.webform.test_confirmation_none.yml |    2 +
 ...webform.webform.test_confirmation_page.yml |    2 +
 ....webform.test_confirmation_page_custom.yml |    2 +
 .../webform.webform.test_confirmation_url.yml |    2 +
 ....webform.test_confirmation_url_message.yml |    2 +
 .../install/webform.webform.test_element.yml  |    2 +
 .../webform.webform.test_element_access.yml   |    2 +
 .../webform.webform.test_element_actions.yml  |    3 +
 ...m.webform.test_element_actions_buttons.yml |    4 +-
 .../webform.webform.test_element_address.yml  |    2 +
 ...form.webform.test_element_allowed_tags.yml |    2 +
 ...ebform.webform.test_element_attributes.yml |    2 +
 ...form.webform.test_element_autocomplete.yml |    2 +
 .../webform.webform.test_element_captcha.yml  |    2 +
 .../webform.webform.test_element_checkbox.yml |    3 +
 ...rm.webform.test_element_checkbox_value.yml |    4 +-
 ...ebform.webform.test_element_checkboxes.yml |    2 +
 ...ebform.webform.test_element_codemirror.yml |   15 +-
 ...webform.webform.test_element_composite.yml |    2 +
 ...webform.test_element_composite_wrapper.yml |    2 +
 ...orm.webform.test_element_computed_ajax.yml |    2 +
 ...rm.webform.test_element_computed_debug.yml |    2 +
 ...rm.webform.test_element_computed_token.yml |    2 +
 ...orm.webform.test_element_computed_twig.yml |    2 +
 ...webform.webform.test_element_container.yml |    2 +
 .../webform.webform.test_element_counter.yml  |   11 +
 .../webform.webform.test_element_date.yml     |    3 +
 .../webform.webform.test_element_datelist.yml |    2 +
 .../webform.webform.test_element_datetime.yml |    6 +-
 ...bform.test_element_description_tooltip.yml |    4 +-
 .../webform.webform.test_element_details.yml  |    2 +
 .../webform.webform.test_element_disabled.yml |    4 +-
 ...orm.webform.test_element_email_confirm.yml |    2 +
 ...rm.webform.test_element_email_multiple.yml |    2 +
 ...bform.test_element_entity_autocomplete.yml |    2 +
 ....webform.test_element_entity_reference.yml |    2 +
 ....webform.test_element_excluded_columns.yml |    3 +
 ...webform.test_element_excluded_elements.yml |    3 +
 .../webform.webform.test_element_fieldset.yml |    2 +
 .../webform.webform.test_element_flexbox.yml  |    4 +-
 ...form.webform.test_element_flexbox_flex.yml |    2 +
 .../webform.webform.test_element_format.yml   |    4 +-
 ...orm.webform.test_element_format_custom.yml |    2 +
 ...m.webform.test_element_format_multiple.yml |   19 +-
 ...form.webform.test_element_format_token.yml |   20 +-
 .../webform.webform.test_element_help.yml     |    2 +
 ...form.webform.test_element_help_display.yml |    4 +-
 ...m.webform.test_element_horizontal_rule.yml |    2 +
 ...bform.webform.test_element_html_editor.yml |    2 +
 ...bform.webform.test_element_html_escape.yml |    4 +-
 ...bform.webform.test_element_html_markup.yml |    4 +-
 ...ebform.test_element_ignored_properties.yml |   68 +-
 ...ebform.webform.test_element_image_file.yml |    2 +
 ...webform.test_element_image_file_attach.yml |    4 +-
 ....webform.test_element_image_resolution.yml |    2 +
 ...ebform.webform.test_element_input_mask.yml |    3 +
 .../webform.webform.test_element_invalid.yml  |    2 +
 .../webform.webform.test_element_likert.yml   |    2 +
 ...ebform.webform.test_element_loc_places.yml |    2 +
 ...form.webform.test_element_managed_file.yml |    2 +
 ....webform.test_element_managed_file_dis.yml |    2 +
 ...webform.test_element_managed_file_help.yml |    2 +
 ...ebform.test_element_managed_file_limit.yml |   10 +-
 ...webform.test_element_managed_file_name.yml |    2 +
 ...webform.test_element_managed_file_prev.yml |    2 +
 .../webform.webform.test_element_mapping.yml  |    2 +
 .../webform.webform.test_element_markup.yml   |    2 +
 ...ebform.webform.test_element_media_file.yml |    2 +
 .../webform.webform.test_element_message.yml  |    2 +
 .../webform.webform.test_element_more.yml     |    2 +
 .../webform.webform.test_element_multiple.yml |    2 +
 ...orm.webform.test_element_multiple_date.yml |    2 +
 ...webform.test_element_multiple_property.yml |    4 +-
 ...orm.webform.test_element_multiple_text.yml |    2 +
 .../webform.webform.test_element_options.yml  |    2 +
 .../webform.webform.test_element_other.yml    |    4 +-
 ...bform.webform.test_element_prepopulate.yml |   48 +-
 .../webform.webform.test_element_private.yml  |    2 +
 .../webform.webform.test_element_radios.yml   |    2 +
 .../webform.webform.test_element_range.yml    |    2 +
 .../webform.webform.test_element_rating.yml   |    2 +
 .../webform.webform.test_element_readonly.yml |    2 +
 .../webform.webform.test_element_same.yml     |    2 +
 .../webform.webform.test_element_scale.yml    |  230 +
 .../webform.webform.test_element_section.yml  |    2 +
 .../webform.webform.test_element_select.yml   |    2 +
 ...webform.webform.test_element_signature.yml |    3 +
 .../webform.webform.test_element_states.yml   |    2 +
 ....webform.test_element_submission_views.yml |    2 +
 ...ebform.test_element_submission_views_r.yml |    2 +
 ...m.webform.test_element_submitted_value.yml |    2 +
 .../webform.webform.test_element_table.yml    |  142 +
 ...webform.test_element_table_select_sort.yml |    4 +-
 ...webform.webform.test_element_telephone.yml |    2 +
 ...rm.webform.test_element_term_reference.yml |    2 +
 ....webform.test_element_terms_of_service.yml |    2 +
 ...bform.webform.test_element_text_format.yml |    2 +
 .../webform.webform.test_element_time.yml     |    4 +-
 ...orm.webform.test_element_title_display.yml |    4 +-
 ...bform.webform.test_element_users_roles.yml |    2 +
 ...ebform.test_element_validate_minlength.yml |    2 +
 ...webform.test_element_validate_multiple.yml |    2 +
 ....webform.test_element_validate_pattern.yml |    4 +-
 ...webform.test_element_validate_required.yml |    4 +-
 ...m.webform.test_element_validate_unique.yml |    4 +-
 .../webform.webform.test_element_view.yml     |    4 +-
 .../webform.webform.test_example_elements.yml |    4 +-
 ...ebform.test_example_elements_composite.yml |    4 +-
 ...webform.test_exporter_entity_reference.yml |    2 +
 .../webform.webform.test_exporter_options.yml |    2 +
 ...ebform.webform.test_form_access_denied.yml |    2 +
 .../install/webform.webform.test_form_api.yml |    2 +
 .../webform.webform.test_form_archived.yml    |    2 +
 .../webform.webform.test_form_assets.yml      |    2 +
 .../webform.webform.test_form_autofill.yml    |    2 +
 .../webform.webform.test_form_autofocus.yml   |    2 +
 .../webform.webform.test_form_closed.yml      |    2 +
 ...webform.webform.test_form_confidential.yml |    2 +
 ...bform.webform.test_form_details_toggle.yml |    2 +
 ...webform.test_form_disable_autocomplete.yml |    2 +
 ...webform.webform.test_form_disable_back.yml |    2 +
 ...ebform.test_form_disable_inline_errors.yml |    2 +
 ...form.webform.test_form_draft_anonymous.yml |    2 +
 ....webform.test_form_draft_authenticated.yml |    2 +
 ...bform.webform.test_form_draft_multiple.yml |    2 +
 ...ebform.webform.test_form_inline_errors.yml |    2 +
 .../webform.webform.test_form_limit.yml       |    2 +
 ...m.webform.test_form_limit_total_unique.yml |    2 +
 ...rm.webform.test_form_limit_user_unique.yml |    2 +
 .../webform.webform.test_form_limit_wait.yml  |    2 +
 .../webform.webform.test_form_long_100.yml    |    2 +
 .../webform.webform.test_form_long_200.yml    |    2 +
 .../webform.webform.test_form_long_300.yml    |    2 +
 .../webform.webform.test_form_novalidate.yml  |    2 +
 .../webform.webform.test_form_opening.yml     |    4 +-
 .../webform.webform.test_form_prepopulate.yml |    3 +
 .../webform.webform.test_form_preview.yml     |    2 +
 .../webform.webform.test_form_properties.yml  |    2 +
 .../webform.webform.test_form_remote_addr.yml |    2 +
 .../webform.webform.test_form_required.yml    |    2 +
 .../webform.webform.test_form_reset.yml       |    2 +
 ...orm.webform.test_form_results_disabled.yml |    2 +
 .../webform.webform.test_form_submit_back.yml |    2 +
 .../webform.webform.test_form_submit_once.yml |    2 +
 .../webform.webform.test_form_submit_text.yml |    2 +
 .../webform.webform.test_form_template.yml    |    2 +
 .../webform.webform.test_form_unsaved.yml     |    2 +
 ...bform.webform.test_form_unsaved_wizard.yml |    2 +
 .../webform.webform.test_form_validate.yml    |    2 +
 ...ebform.webform.test_form_wizard_access.yml |    2 +
 ...form.webform.test_form_wizard_advanced.yml |    2 +
 ...webform.webform.test_form_wizard_basic.yml |    2 +
 ...m.webform.test_form_wizard_conditional.yml |    2 +
 ...ebform.webform.test_form_wizard_custom.yml |    2 +
 ...webform.webform.test_form_wizard_links.yml |    2 +
 ...form.webform.test_form_wizard_long_100.yml |    2 +
 ...form.webform.test_form_wizard_long_200.yml |    2 +
 ...form.webform.test_form_wizard_long_300.yml |    2 +
 ...form.webform.test_form_wizard_validate.yml |    2 +
 ...webform.test_form_wizard_validate_comp.yml |    2 +
 .../webform.webform.test_handler_action.yml   |    2 +
 .../webform.webform.test_handler_email.yml    |    4 +-
 ...rm.webform.test_handler_email_advanced.yml |    6 +-
 ...orm.webform.test_handler_email_mapping.yml |    4 +-
 ...bform.webform.test_handler_email_roles.yml |    4 +-
 ...form.webform.test_handler_email_states.yml |    4 +-
 ...ebform.webform.test_handler_email_twig.yml |    6 +-
 .../webform.webform.test_handler_settings.yml |    2 +
 ...ebform.webform.test_libraries_optional.yml |    4 +-
 .../webform.webform.test_rendering.yml        |    4 +-
 .../install/webform.webform.test_states.yml   |    4 +-
 ...bform.webform.test_states_autocomplete.yml |    2 +
 .../webform.webform.test_states_crosspage.yml |    2 +
 .../webform.webform.test_states_disabled.yml  |    2 +
 ...bform.webform.test_states_server_clear.yml |    2 +
 ...ebform.webform.test_states_server_comp.yml |    2 +
 ....webform.test_states_server_containers.yml |    2 +
 ...form.webform.test_states_server_custom.yml |    2 +
 ...form.webform.test_states_server_hidden.yml |    2 +
 ...form.webform.test_states_server_likert.yml |    2 +
 ...rm.webform.test_states_server_multiple.yml |    2 +
 ...form.webform.test_states_server_nested.yml |    2 +
 ...orm.webform.test_states_server_preview.yml |    2 +
 ...rm.webform.test_states_server_required.yml |    2 +
 ...ebform.webform.test_states_server_save.yml |    2 +
 ...form.webform.test_states_server_wizard.yml |    2 +
 .../webform.webform.test_states_triggers.yml  |    2 +
 .../webform.webform.test_submission_label.yml |    2 +
 .../webform.webform.test_submission_log.yml   |    2 +
 .../webform.webform.test_submission_views.yml |    2 +
 .../install/webform.webform.test_token.yml    |   10 +-
 ...rm.webform.test_token_submission_value.yml |   39 +-
 ...webform.webform.test_token_view_update.yml |    8 +-
 .../webform.webform.test_variant_multiple.yml |   12 +-
 .../webform.webform.test_variant_override.yml |    4 +-
 ...webform.webform.test_variant_randomize.yml |    6 +-
 ..._test.test_element_description_tooltip.inc |    2 +-
 .../webform_test/webform_test.info.yml        |    6 +-
 .../modules/webform_test/webform_test.module  |   22 +
 .../webform_test_ajax.info.yml                |    6 +-
 .../webform_test_alter_hooks.info.yml         |    6 +-
 .../webform_test_block_context.info.yml       |    6 +-
 .../webform_test_block_custom.info.yml        |    6 +-
 ...bform_test_block_submission_limit.info.yml |    6 +-
 .../webform_test_config_performance.info.yml  |    6 +-
 ....webform.test_element_comp_file_plugin.yml |    2 +
 ....webform.test_element_composite_plugin.yml |    2 +
 .../webform.webform.test_element_plugin.yml   |    2 +
 .../webform_test_element.info.yml             |    6 +-
 .../webform_test_element_input_masks.info.yml |    6 +-
 ...bform.test_element_entity_reference_vs.yml |    2 +
 ...bform_test_entity_reference_views.info.yml |    6 +-
 .../webform_test_exporter.info.yml            |    6 +-
 ...ebform.webform.test_handler_conditions.yml |    2 +
 .../webform.webform.test_handler_test.yml     |    4 +-
 .../webform_test_handler.info.yml             |    6 +-
 ...webform_test_handler_invoke_alter.info.yml |    6 +-
 ...ebform.webform.test_handler_remote_get.yml |   22 +-
 ...bform.webform.test_handler_remote_post.yml |   22 +-
 ....webform.test_handler_remote_post_cast.yml |    4 +-
 ....webform.test_handler_remote_post_file.yml |    6 +-
 ...ebform.webform.test_handler_remote_put.yml |   22 +-
 .../webform_test_handler_remote_post.info.yml |    6 +-
 .../webform_test_markup.info.yml              |    6 +-
 .../webform_test_message_custom.info.yml      |    6 +-
 .../install/webform.webform.test_options.yml  |    2 +
 .../webform_test_options.info.yml             |    6 +-
 .../webform_test_paragraphs.info.yml          |    6 +-
 .../webform_test_rest.info.yml                |    6 +-
 .../webform.webform.test_submissions.yml      |    2 +
 .../webform_test_submissions.info.yml         |    6 +-
 ...webform_test_third_party_settings.info.yml |    6 +-
 .../webform.webform.test_translation.yml      |    4 +-
 .../webform_test_translation.info.yml         |    6 +-
 ...webform_test_translation_lingotek.info.yml |    6 +-
 .../webform_test_validate.info.yml            |    6 +-
 .../webform_test_variant.info.yml             |    6 +-
 .../webform_test_views.info.yml               |    6 +-
 .../webform_test_wizard_custom.info.yml       |    6 +-
 .../Element/WebformElementCodeMirrorTest.php  |    9 +-
 .../Element/WebformElementCounterTest.php     |    3 +
 .../Element/WebformElementFormatTest.php      |    5 +
 .../WebformElementIgnoredPropertiesTest.php   |    3 +-
 .../WebformElementManagedFileLimitTest.php    |   10 +
 .../Element/WebformElementManagedFileTest.php |   19 +
 .../Element/WebformElementMediaFileTest.php   |    2 +-
 .../WebformElementPluginDefinitionsTest.php   |   70 +-
 .../WebformElementPluginPropertiesTest.php    |  152 +-
 .../Element/WebformElementPrepopulateTest.php |   56 +-
 .../Element/WebformElementScaleTest.php       |   50 +
 .../Element/WebformElementSignatureTest.php   |   44 +-
 ...bformElementSubmissionViewsReplaceTest.php |    4 +-
 .../Element/WebformElementTableTest.php       |  179 +-
 .../WebformElementTermReferenceTest.php       |   18 +
 .../Handler/WebformHandlerRemotePostTest.php  |    2 +-
 .../Settings/WebformSettingsDraftTest.php     |    7 +
 .../WebformSettingsPrepopulateTest.php        |    2 +-
 .../Token/WebformTokenSubmissionValueTest.php |    5 +
 .../WebformEntityElementsValidationTest.php   |   26 +
 .../Kernel/WebformSubmissionStorageTest.php   |    2 +-
 .../Unit/Utility/WebformElementHelperTest.php |   29 +
 .../Unit/Utility/WebformOptionsHelperTest.php |    1 +
 .../webform_test_bartik.info.yml              |    6 +-
 web/modules/webform/webform.info.yml          |    6 +-
 web/modules/webform/webform.libraries.yml     |   16 +-
 web/modules/webform/webform.module            |    2 +-
 web/modules/webform/webform.tokens.inc        |   14 +-
 514 files changed, 13671 insertions(+), 820 deletions(-)
 create mode 100644 web/modules/webform/css/webform.element.scale.css
 create mode 100644 web/modules/webform/css/webform.element.table.css
 create mode 100644 web/modules/webform/images/addons/emfluence_webform.png
 create mode 100644 web/modules/webform/images/addons/hn_react_webform.png
 create mode 100644 web/modules/webform/images/addons/react_webform_backend.svg
 create mode 100644 web/modules/webform/images/addons/webform_calculation.png
 create mode 100644 web/modules/webform/images/addons/webform_rest.png
 create mode 100644 web/modules/webform/images/addons/webform_sugarcrm.png
 delete mode 100644 web/modules/webform/images/addons/webform_sugarcrm.svg
 create mode 100644 web/modules/webform/src/Element/WebformScale.php
 create mode 100644 web/modules/webform/src/Element/WebformTable.php
 create mode 100644 web/modules/webform/src/Element/WebformTableRow.php
 create mode 100644 web/modules/webform/src/Entity/Webform.php.orig
 create mode 100644 web/modules/webform/src/Plugin/WebformElement/OptionsBase.php.orig
 create mode 100644 web/modules/webform/src/Plugin/WebformElement/TextBase.php.orig
 create mode 100644 web/modules/webform/src/Plugin/WebformElement/WebformScale.php
 create mode 100644 web/modules/webform/src/Plugin/WebformElement/WebformTable.php
 create mode 100644 web/modules/webform/src/Plugin/WebformElement/WebformTableRow.php
 create mode 100644 web/modules/webform/src/Plugin/WebformElementBase.php.orig
 create mode 100644 web/modules/webform/src/Routing/WebformUncacheableResponse.php
 create mode 100644 web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_scale.yml
 create mode 100644 web/modules/webform/tests/src/Functional/Element/WebformElementScaleTest.php

diff --git a/composer.json b/composer.json
index b8a5479888..51b8d4f5ca 100644
--- a/composer.json
+++ b/composer.json
@@ -182,7 +182,7 @@
         "drupal/views_fieldsets": "3.3",
         "drupal/views_infinite_scroll": "1.6",
         "drupal/views_slideshow": "4.4",
-        "drupal/webform": "5.9",
+        "drupal/webform": "5.11",
         "drupal/webform_views": "5.0-alpha2",
         "drush-ops/behat-drush-endpoint": "0.0.5",
         "drush/drush": "9.7.1",
diff --git a/composer.lock b/composer.lock
index 46c614090b..1881d1b0a0 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "823616d77c082976843eeb97ed622870",
+    "content-hash": "b2ea22c5bf28d938f9d1294ec1786476",
     "packages": [
         {
             "name": "alchemy/zippy",
@@ -6088,8 +6088,7 @@
             "homepage": "https://www.drupal.org/project/migrate_devel",
             "support": {
                 "source": "http://cgit.drupalcode.org/migrate_devel"
-            },
-            "time": "2017-06-25T23:46:13+00:00"
+            }
         },
         {
             "name": "drupal/migrate_plus",
@@ -8458,17 +8457,17 @@
         },
         {
             "name": "drupal/webform",
-            "version": "5.9.0",
+            "version": "5.11.0",
             "source": {
                 "type": "git",
                 "url": "https://git.drupalcode.org/project/webform.git",
-                "reference": "8.x-5.9"
+                "reference": "8.x-5.11"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://ftp.drupal.org/files/projects/webform-8.x-5.9.zip",
-                "reference": "8.x-5.9",
-                "shasum": "fb49b16dd0c421512834fc50c811fa2cd6c48121"
+                "url": "https://ftp.drupal.org/files/projects/webform-8.x-5.11.zip",
+                "reference": "8.x-5.11",
+                "shasum": "2a8664687d2b0b6071bab011dbbb431e15c83710"
             },
             "require": {
                 "drupal/core": "^8.7.7 || ^9"
@@ -8479,14 +8478,14 @@
                 "drupal/captcha": "~1.0",
                 "drupal/chosen": "~2.6",
                 "drupal/devel": "*",
-                "drupal/entity_print": "^2.1",
+                "drupal/entity_print": "*",
                 "drupal/gnode": "*",
-                "drupal/group": "~1.0",
+                "drupal/group": "*",
                 "drupal/mailsystem": "~4.1",
                 "drupal/select2": "~1.1",
                 "drupal/smtp": "~1.0",
                 "drupal/telephone_validation": "^2.2",
-                "drupal/token": "~1.3",
+                "drupal/token": "*",
                 "drupal/webform_access": "*",
                 "drupal/webform_attachment": "*",
                 "drupal/webform_devel": "*",
@@ -8499,12 +8498,9 @@
             },
             "type": "drupal-module",
             "extra": {
-                "branch-alias": {
-                    "dev-5.x": "5.x-dev"
-                },
                 "drupal": {
-                    "version": "8.x-5.9",
-                    "datestamp": "1584560013",
+                    "version": "8.x-5.11",
+                    "datestamp": "1588785899",
                     "security-coverage": {
                         "status": "covered",
                         "message": "Covered by Drupal's security advisory policy"
@@ -8518,7 +8514,7 @@
             },
             "notification-url": "https://packages.drupal.org/8/downloads",
             "license": [
-                "GPL-2.0+"
+                "GPL-2.0-or-later"
             ],
             "authors": [
                 {
@@ -8532,8 +8528,9 @@
                     "role": "Co-maintainer"
                 },
                 {
-                    "name": "bucefal91",
-                    "homepage": "https://www.drupal.org/user/504128"
+                    "name": "Contributors",
+                    "homepage": "https://www.drupal.org/node/7404/committers",
+                    "role": "Contributor"
                 },
                 {
                     "name": "fenstrat",
@@ -13152,5 +13149,6 @@
     "platform-dev": [],
     "platform-overrides": {
         "php": "7.0.8"
-    }
+    },
+    "plugin-api-version": "1.1.0"
 }
diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php
index fc6dc637f7..5fcf9b1039 100644
--- a/vendor/composer/autoload_classmap.php
+++ b/vendor/composer/autoload_classmap.php
@@ -2224,8 +2224,6 @@
     'Drupal\\Core\\Language\\LanguageManager' => $baseDir . '/web/core/lib/Drupal/Core/Language/LanguageManager.php',
     'Drupal\\Core\\Language\\LanguageManagerInterface' => $baseDir . '/web/core/lib/Drupal/Core/Language/LanguageManagerInterface.php',
     'Drupal\\Core\\Layout\\Annotation\\Layout' => $baseDir . '/web/core/lib/Drupal/Core/Layout/Annotation/Layout.php',
-    'Drupal\\Core\\Layout\\Icon\\IconBuilderInterface' => $baseDir . '/web/core/lib/Drupal/Core/Layout/Icon/IconBuilderInterface.php',
-    'Drupal\\Core\\Layout\\Icon\\SvgIconBuilder' => $baseDir . '/web/core/lib/Drupal/Core/Layout/Icon/SvgIconBuilder.php',
     'Drupal\\Core\\Layout\\LayoutDefault' => $baseDir . '/web/core/lib/Drupal/Core/Layout/LayoutDefault.php',
     'Drupal\\Core\\Layout\\LayoutDefinition' => $baseDir . '/web/core/lib/Drupal/Core/Layout/LayoutDefinition.php',
     'Drupal\\Core\\Layout\\LayoutInterface' => $baseDir . '/web/core/lib/Drupal/Core/Layout/LayoutInterface.php',
diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php
index 126478a282..fe8678ed14 100644
--- a/vendor/composer/autoload_real.php
+++ b/vendor/composer/autoload_real.php
@@ -13,6 +13,9 @@ public static function loadClassLoader($class)
         }
     }
 
+    /**
+     * @return \Composer\Autoload\ClassLoader
+     */
     public static function getLoader()
     {
         if (null !== self::$loader) {
diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php
index 1cf3d2e859..4a69a92670 100644
--- a/vendor/composer/autoload_static.php
+++ b/vendor/composer/autoload_static.php
@@ -2885,8 +2885,6 @@ class ComposerStaticInit5c689ffcd54b9e495ed983fdce09b530
         'Drupal\\Core\\Language\\LanguageManager' => __DIR__ . '/../..' . '/web/core/lib/Drupal/Core/Language/LanguageManager.php',
         'Drupal\\Core\\Language\\LanguageManagerInterface' => __DIR__ . '/../..' . '/web/core/lib/Drupal/Core/Language/LanguageManagerInterface.php',
         'Drupal\\Core\\Layout\\Annotation\\Layout' => __DIR__ . '/../..' . '/web/core/lib/Drupal/Core/Layout/Annotation/Layout.php',
-        'Drupal\\Core\\Layout\\Icon\\IconBuilderInterface' => __DIR__ . '/../..' . '/web/core/lib/Drupal/Core/Layout/Icon/IconBuilderInterface.php',
-        'Drupal\\Core\\Layout\\Icon\\SvgIconBuilder' => __DIR__ . '/../..' . '/web/core/lib/Drupal/Core/Layout/Icon/SvgIconBuilder.php',
         'Drupal\\Core\\Layout\\LayoutDefault' => __DIR__ . '/../..' . '/web/core/lib/Drupal/Core/Layout/LayoutDefault.php',
         'Drupal\\Core\\Layout\\LayoutDefinition' => __DIR__ . '/../..' . '/web/core/lib/Drupal/Core/Layout/LayoutDefinition.php',
         'Drupal\\Core\\Layout\\LayoutInterface' => __DIR__ . '/../..' . '/web/core/lib/Drupal/Core/Layout/LayoutInterface.php',
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index e77e721aed..d30dd24a88 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -8722,18 +8722,18 @@
     },
     {
         "name": "drupal/webform",
-        "version": "5.9.0",
-        "version_normalized": "5.9.0.0",
+        "version": "5.11.0",
+        "version_normalized": "5.11.0.0",
         "source": {
             "type": "git",
             "url": "https://git.drupalcode.org/project/webform.git",
-            "reference": "8.x-5.9"
+            "reference": "8.x-5.11"
         },
         "dist": {
             "type": "zip",
-            "url": "https://ftp.drupal.org/files/projects/webform-8.x-5.9.zip",
-            "reference": "8.x-5.9",
-            "shasum": "fb49b16dd0c421512834fc50c811fa2cd6c48121"
+            "url": "https://ftp.drupal.org/files/projects/webform-8.x-5.11.zip",
+            "reference": "8.x-5.11",
+            "shasum": "2a8664687d2b0b6071bab011dbbb431e15c83710"
         },
         "require": {
             "drupal/core": "^8.7.7 || ^9"
@@ -8744,14 +8744,14 @@
             "drupal/captcha": "~1.0",
             "drupal/chosen": "~2.6",
             "drupal/devel": "*",
-            "drupal/entity_print": "^2.1",
+            "drupal/entity_print": "*",
             "drupal/gnode": "*",
-            "drupal/group": "~1.0",
+            "drupal/group": "*",
             "drupal/mailsystem": "~4.1",
             "drupal/select2": "~1.1",
             "drupal/smtp": "~1.0",
             "drupal/telephone_validation": "^2.2",
-            "drupal/token": "~1.3",
+            "drupal/token": "*",
             "drupal/webform_access": "*",
             "drupal/webform_attachment": "*",
             "drupal/webform_devel": "*",
@@ -8764,12 +8764,9 @@
         },
         "type": "drupal-module",
         "extra": {
-            "branch-alias": {
-                "dev-5.x": "5.x-dev"
-            },
             "drupal": {
-                "version": "8.x-5.9",
-                "datestamp": "1584560013",
+                "version": "8.x-5.11",
+                "datestamp": "1588785899",
                 "security-coverage": {
                     "status": "covered",
                     "message": "Covered by Drupal's security advisory policy"
@@ -8784,7 +8781,7 @@
         "installation-source": "dist",
         "notification-url": "https://packages.drupal.org/8/downloads",
         "license": [
-            "GPL-2.0+"
+            "GPL-2.0-or-later"
         ],
         "authors": [
             {
@@ -8798,8 +8795,9 @@
                 "role": "Co-maintainer"
             },
             {
-                "name": "bucefal91",
-                "homepage": "https://www.drupal.org/user/504128"
+                "name": "Contributors",
+                "homepage": "https://www.drupal.org/node/7404/committers",
+                "role": "Contributor"
             },
             {
                 "name": "fenstrat",
diff --git a/web/modules/webform/composer.json b/web/modules/webform/composer.json
index aa2a542757..1b7cef09ee 100644
--- a/web/modules/webform/composer.json
+++ b/web/modules/webform/composer.json
@@ -2,7 +2,7 @@
   "name": "drupal/webform",
   "description": "Enables the creation of webforms and questionnaires.",
   "type": "drupal-module",
-  "license": "GPL-2.0+",
+  "license": "GPL-2.0-or-later",
   "minimum-stability": "dev",
   "homepage": "https://drupal.org/project/webform",
   "authors": [
@@ -15,6 +15,11 @@
       "name": "Alexander Trotsenko (bucefal91)",
       "homepage": "https://www.drupal.org/u/bucefal91",
       "role": "Co-maintainer"
+    },
+    {
+        "name": "Contributors",
+        "homepage": "https://www.drupal.org/node/7404/committers",
+        "role": "Contributor"
     }
   ],
   "support": {
diff --git a/web/modules/webform/composer.libraries.json b/web/modules/webform/composer.libraries.json
index 5db831b584..48cbc97ef7 100644
--- a/web/modules/webform/composer.libraries.json
+++ b/web/modules/webform/composer.libraries.json
@@ -2,7 +2,7 @@
     "name": "drupal/webform",
     "description": "Enables the creation of webforms and questionnaires.",
     "type": "drupal-module",
-    "license": "GPL-2.0+",
+    "license": "GPL-2.0-or-later",
     "minimum-stability": "dev",
     "homepage": "https://drupal.org/project/webform",
     "authors": [
@@ -15,11 +15,16 @@
             "name": "Alexander Trotsenko (bucefal91)",
             "homepage": "https://www.drupal.org/u/bucefal91",
             "role": "Co-maintainer"
+        },
+        {
+            "name": "Contributors",
+            "homepage": "https://www.drupal.org/node/7404/committers",
+            "role": "Contributor"
         }
     ],
     "support": {
         "issues": "https://www.drupal.org/project/issues/webform?version=8.x",
-        "source": "http://cgit.drupalcode.org/webform",
+        "source": "https://git.drupalcode.org/project/webform",
         "docs": "https://www.drupal.org/docs/8/modules/webform",
         "forum": "https://drupal.stackexchange.com/questions/tagged/webform"
     },
@@ -64,13 +69,13 @@
             "type": "package",
             "package": {
                 "name": "ckeditor/autogrow",
-                "version": "4.11.4",
+                "version": "4.14.0",
                 "type": "drupal-library",
                 "extra": {
                     "installer-name": "ckeditor.autogrow"
                 },
                 "dist": {
-                    "url": "https://download.ckeditor.com/autogrow/releases/autogrow_4.11.4.zip",
+                    "url": "https://download.ckeditor.com/autogrow/releases/autogrow_4.14.0.zip",
                     "type": "zip"
                 },
                 "require": {
@@ -100,13 +105,13 @@
             "type": "package",
             "package": {
                 "name": "ckeditor/fakeobjects",
-                "version": "4.11.4",
+                "version": "4.14.0",
                 "type": "drupal-library",
                 "extra": {
                     "installer-name": "ckeditor.fakeobjects"
                 },
                 "dist": {
-                    "url": "https://download.ckeditor.com/fakeobjects/releases/fakeobjects_4.11.4.zip",
+                    "url": "https://download.ckeditor.com/fakeobjects/releases/fakeobjects_4.14.0.zip",
                     "type": "zip"
                 },
                 "require": {
@@ -118,13 +123,13 @@
             "type": "package",
             "package": {
                 "name": "ckeditor/image",
-                "version": "4.11.4",
+                "version": "4.14.0",
                 "type": "drupal-library",
                 "extra": {
                     "installer-name": "ckeditor.image"
                 },
                 "dist": {
-                    "url": "https://download.ckeditor.com/image/releases/image_4.11.4.zip",
+                    "url": "https://download.ckeditor.com/image/releases/image_4.14.0.zip",
                     "type": "zip"
                 },
                 "require": {
@@ -136,13 +141,13 @@
             "type": "package",
             "package": {
                 "name": "ckeditor/link",
-                "version": "4.11.4",
+                "version": "4.14.0",
                 "type": "drupal-library",
                 "extra": {
                     "installer-name": "ckeditor.link"
                 },
                 "dist": {
-                    "url": "https://download.ckeditor.com/link/releases/link_4.11.4.zip",
+                    "url": "https://download.ckeditor.com/link/releases/link_4.14.0.zip",
                     "type": "zip"
                 },
                 "require": {
@@ -280,13 +285,13 @@
             "type": "package",
             "package": {
                 "name": "jquery/intl-tel-input",
-                "version": "16.0.0",
+                "version": "16.1.0",
                 "type": "drupal-library",
                 "extra": {
                     "installer-name": "jquery.intl-tel-input"
                 },
                 "dist": {
-                    "url": "https://github.com/jackocnr/intl-tel-input/archive/v16.0.0.zip",
+                    "url": "https://github.com/jackocnr/intl-tel-input/archive/v16.1.0.zip",
                     "type": "zip"
                 },
                 "require": {
diff --git a/web/modules/webform/config/install/webform.settings.yml b/web/modules/webform/config/install/webform.settings.yml
index d27ffa8cbb..e7cb9d3610 100644
--- a/web/modules/webform/config/install/webform.settings.yml
+++ b/web/modules/webform/config/install/webform.settings.yml
@@ -185,7 +185,7 @@ file:
   file_private_redirect: true
   file_private_redirect_message: 'Please login to access the uploaded file.'
   default_max_filesize: ''
-  default_managed_file_extensions: 'gif jpg jpeg png bmp eps tif pict psd txt rtf html odf pdf doc docx ppt pptx xls xlsx xml avi mov mp3 ogg wav bz2 dmg gz jar rar sit svg tar zip'
+  default_managed_file_extensions: 'gif jpg jpeg png bmp eps tif pict psd txt rtf html odf pdf doc docx ppt pptx xls xlsx xml avi mov mp3 mp4 ogg wav bz2 dmg gz jar rar sit svg tar zip'
   default_audio_file_extensions: 'mp3 ogg wav'
   default_document_file_extensions: 'txt rtf pdf doc docx odt ppt pptx odp xls xlsx ods'
   default_image_file_extensions: 'gif jpg jpeg png'
diff --git a/web/modules/webform/config/install/webform.webform.contact.yml b/web/modules/webform/config/install/webform.webform.contact.yml
index 20f8a0cc38..c580c0bbe3 100644
--- a/web/modules/webform/config/install/webform.webform.contact.yml
+++ b/web/modules/webform/config/install/webform.webform.contact.yml
@@ -39,7 +39,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': 'Send message'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -153,6 +153,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -275,3 +276,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/css/webform.ajax.css b/web/modules/webform/css/webform.ajax.css
index cc9922d65a..88413c4513 100644
--- a/web/modules/webform/css/webform.ajax.css
+++ b/web/modules/webform/css/webform.ajax.css
@@ -23,6 +23,7 @@
  */
 .webform-ajax-messages {
   position: fixed;
+  z-index: 100;
   bottom: 0;
   width: 100%;
 }
diff --git a/web/modules/webform/css/webform.element.scale.css b/web/modules/webform/css/webform.element.scale.css
new file mode 100644
index 0000000000..521401e70e
--- /dev/null
+++ b/web/modules/webform/css/webform.element.scale.css
@@ -0,0 +1,226 @@
+/**
+ * @file
+ * Element scale styles.
+ */
+
+.webform-scale {
+  display: inline-block;
+}
+
+/**
+ * Options.
+ */
+.webform-scale-options {
+  white-space: nowrap;
+  margin: 0 -4px;
+}
+
+.webform-scale-options .form-item {
+  display: inline-block;
+  margin: 0 4px;
+}
+
+/**
+ * Option.
+ */
+.webform-scale-option {
+  display: inline-block;
+}
+
+.webform-scale-options input + label,
+.webform-scale-options input + label.option {
+  display: inline-block;
+}
+
+.webform-scale-options input + label {
+  text-align: center;
+  color: #666;
+  border: 3px solid #ccc;
+  border-radius: 50%;
+  background-color: #fff;
+  margin: 0;
+  /* Default. */
+  width: 36px;
+  height: 36px;
+  line-height: 36px;
+  font-size: 1.2em;
+}
+
+/**
+ * Text.
+ */
+.webform-scale-text {
+  position: relative;
+  height: 1em;
+  line-height: 1em;
+  margin: 4px 2px;
+}
+
+.webform-scale-text-min,
+.webform-scale-text-max {
+  position: absolute;
+}
+
+[dir="ltr"] .webform-scale-text-min {
+  left: 0;
+  text-align: left;
+}
+
+[dir="ltr"] .webform-scale-text-max {
+  right: 0;
+  text-align: right;
+}
+
+[dir="rtl"] .webform-scale-text-min {
+  right: 0;
+  text-align: right;
+}
+
+[dir="rtl"] .webform-scale-text-max {
+  left: 0;
+  text-align: left;
+}
+
+/**
+ * States.
+ */
+.webform-scale-options input:hover + label {
+  color: #333;
+  border-color: #999;
+}
+
+.webform-scale-options input:focus + label {
+  color: #333;
+  border-color: #999;
+  box-shadow: 0 0 5px #999;
+}
+
+.webform-scale-options input:checked + label {
+  color: #000;
+  border-color: #0074bd;
+}
+
+.webform-scale-options input:checked:focus + label {
+  box-shadow: 0 0 5px #0074bd;
+}
+
+/******************************************************************************/
+
+/**
+ * Small.
+ */
+.webform-scale-small .form-item {
+  margin: 4px 1px;
+}
+
+.webform-scale-small .webform-scale-text {
+  margin: 4px 1px;
+}
+
+.webform-scale-small input + label {
+  width: 24px;
+  height: 24px;
+  line-height: 24px;
+  font-size: 1.1em;
+  border-width: 2px;
+}
+
+/**
+ * Medium.
+ */
+.webform-scale-medium input + label {
+  width: 36px;
+  height: 36px;
+  line-height: 36px;
+  font-size: 1.2em;
+}
+
+@media (max-width: 768px) {
+  .webform-scale-medium .form-item {
+    margin: 4px 1px;
+  }
+
+  .webform-scale-medium .webform-scale-text {
+    margin: 4px 1px;
+  }
+
+  .webform-scale-medium input + label {
+    width: 24px;
+    height: 24px;
+    line-height: 24px;
+    font-size: 1.1em;
+    border-width: 2px;
+  }
+}
+
+/**
+ * Large.
+ */
+.webform-scale-large input + label {
+  width: 48px;
+  height: 48px;
+  line-height: 48px;
+  font-size: 1.5em;
+}
+
+@media (max-width: 768px) {
+  .webform-scale-large .form-item {
+    margin: 4px 1px;
+  }
+
+  .webform-scale-large .webform-scale-text {
+    margin: 4px 1px;
+  }
+
+  .webform-scale-large input + label {
+    width: 36px;
+    height: 36px;
+    line-height: 36px;
+    font-size: 1.2em;
+    border-width: 2px;
+  }
+}
+
+/******************************************************************************/
+
+/**
+ * Square.
+ */
+.webform-scale-square input + label {
+  border-radius: 3px;
+}
+
+/**
+ * Flexbox.
+ */
+.webform-scale-flexbox {
+  display: block;
+}
+
+.webform-scale-flexbox .webform-scale-options {
+  display: flex;
+  flex-wrap: wrap;
+  margin: 5px -5px;
+}
+
+.webform-scale-flexbox .webform-scale-option {
+  flex: 1;
+  margin: 0 5px;
+}
+
+.webform-scale-flexbox .form-item {
+  margin: 0 !important;
+  display: table;
+  width: 100%;
+  height: 100%;
+}
+.webform-scale-flexbox input + label {
+  display: table-cell;
+  width: 100%;
+  vertical-align: middle;
+  border-radius: 3px;
+}
+
+.webform-scale-flexbox .webform-scale-text {
+  margin: 5px;
+}
diff --git a/web/modules/webform/css/webform.element.table.css b/web/modules/webform/css/webform.element.table.css
new file mode 100644
index 0000000000..e2f34833eb
--- /dev/null
+++ b/web/modules/webform/css/webform.element.table.css
@@ -0,0 +1,58 @@
+/**
+ * @file
+ * Table element styles.
+ */
+
+.webform-table td {
+  vertical-align: top;
+}
+
+.webform-table td select,
+.webform-table td .form-type-textfield input,
+.webform-table td .form-type-email input,
+.webform-table td .form-type-url input,
+.webform-table td .form-type-tel input,
+.webform-table td .form-type-entity-autocomplete input,
+.webform-table td .form-type-webform-autocomplete input {
+  width: 100%;
+}
+
+.webform-table td .container-inline select,
+.form-type-webform-multiple.webform-has-field-prefix td select,
+.form-type-webform-multiple.webform-has-field-suffix td select,
+.form-type-webform-multiple.webform-has-field-prefix td input,
+.form-type-webform-multiple.webform-has-field-suffix td input {
+  width: auto;
+}
+
+.webform-table td .form-type-datetime .form-type-textfield input {
+  width: 12em;
+}
+
+/**
+ * Add margin between stacked form items.
+ */
+.webform-table tr td .form-item {
+  margin-top: 1em;
+}
+
+.webform-table tr td > .form-item:first-child,
+.webform-table tr td > div > .form-item:first-child {
+  margin-top: 0;
+}
+
+/**
+ * Fix margin be checkboxes and radios.
+ */
+.webform-table tr td .form-checkboxes .form-item,
+.webform-table tr td .form-radios .form-item {
+  margin-top: 0.4em;
+  margin-bottom: 0.4em;
+}
+
+/**
+ * IMCE tweaks
+ */
+.webform-table .imce-url-button {
+  display: block;
+}
diff --git a/web/modules/webform/css/webform.element.tableselect.css b/web/modules/webform/css/webform.element.tableselect.css
index b93cdbd752..757b01f482 100644
--- a/web/modules/webform/css/webform.element.tableselect.css
+++ b/web/modules/webform/css/webform.element.tableselect.css
@@ -2,7 +2,7 @@
  * @file
  * Table select element styles.
  *
- * @see /webform/test_element_table
+ * @see /webform/test_element_table_select_sort
  */
 
 /* Make the first column containing a checkbox/radio as small as possible. */
diff --git a/web/modules/webform/css/webform.theme.seven.css b/web/modules/webform/css/webform.theme.seven.css
index 152b59c2c1..12952d79c0 100644
--- a/web/modules/webform/css/webform.theme.seven.css
+++ b/web/modules/webform/css/webform.theme.seven.css
@@ -128,7 +128,8 @@ pre.webform-codemirror-runmode {
 /* System tray divider */
 
 .ui-dialog.ui-dialog-off-canvas.webform-off-canvas {
-  z-index: 599 !important; /* Place off canvas under dialog overlay */
+  /* Place un admin menu toolbar (z-index: 502) */
+  z-index: 501 !important;
 }
 
 .ui-dialog.ui-dialog-off-canvas .ui-resizable-w {
diff --git a/web/modules/webform/docs/RELEASE-NOTES.md b/web/modules/webform/docs/RELEASE-NOTES.md
index 0e96024c6e..33c48b2ecc 100644
--- a/web/modules/webform/docs/RELEASE-NOTES.md
+++ b/web/modules/webform/docs/RELEASE-NOTES.md
@@ -15,7 +15,7 @@ Steps for creating a new release
     # Remove files that should never be reviewed.
     cd modules/sandbox/webform
     rm *.patch interdiff-*
-    
+
 [PHP](https://www.drupal.org/node/1587138)
 
     # Check Drupal PHP coding standards
@@ -33,12 +33,12 @@ Steps for creating a new release
     # Install Eslint. (One-time)
     cd /var/www/sites/d8_webform/web/core
     yarn install
-    
+
     # Check Drupal JavaScript (ES5) legacy coding standards.
     cd /var/www/sites/d8_webform/web
     core/node_modules/.bin/eslint --no-eslintrc -c=core/.eslintrc.legacy.json --ext=.js modules/sandbox/webform > ~/webform-javascript-coding-standards.txt
     cat ~/webform-javascript-coding-standards.txt
-          
+
 [CSS](https://www.drupal.org/node/3041002)
 
     # Install Eslint. (One-time)
@@ -59,14 +59,28 @@ Steps for creating a new release
 2. Deprecated code
 ------------------
 
-[phpstan-drupal](https://github.com/mglaman/phpstan-drupal) 
+[drupal-check](https://github.com/mglaman/drupal-check) - RECOMMENDED
+
+`drupal-check` output can not be redirected to a file.
+
+@see [Redirect output to a file #137](https://github.com/mglaman/drupal-check/issues/137)
+
+    cd /var/www/sites/d8_webform/
+    composer require mglaman/drupal-check
+    # Deprecations.
+    vendor/mglaman/drupal-check/drupal-check --no-progress -d web/modules/sandbox/webform
+    # Analysis.
+    vendor/mglaman/drupal-check/drupal-check --no-progress  -a web/modules/sandbox/webform
+
+
+[phpstan-drupal](https://github.com/mglaman/phpstan-drupal)
 [phpstan-drupal-deprecations](https://github.com/mglaman/phpstan-drupal-deprecations)
 
     cd /var/www/sites/d8_webform/
     composer require mglaman/phpstan-drupal
     composer require phpstan/phpstan-deprecation-rules
 
-Create `/var/www/sites/d8_webform/phpstan.neon` 
+Create `/var/www/sites/d8_webform/phpstan.neon`
 
     parameters:
       customRulesetUsed: true
@@ -80,14 +94,13 @@ Create `/var/www/sites/d8_webform/phpstan.neon`
     includes:
       - vendor/mglaman/phpstan-drupal/extension.neon
       - vendor/phpstan/phpstan-deprecation-rules/rules.neon
-    
+
 Run PHPStan with memory limit increased
 
     cd /var/www/sites/d8_webform/
     ./vendor/bin/phpstan --memory-limit=1024M analyse web/modules/sandbox/webform > ~/webform-deprecated.txt
     cat ~/webform-deprecated.txt
 
-    
 3. Review accessibility
 -----------------------
 
@@ -101,11 +114,11 @@ Notes
 
     # Enable accessibility examples.
     drush en -y webform_examples_accessibility
-    
+
     # Text.
-    mkdir -p /var/www/sites/d8_webform/web/modules/sandbox/webform/reports/accessiblity/text  
+    mkdir -p /var/www/sites/d8_webform/web/modules/sandbox/webform/reports/accessiblity/text
     cd /var/www/sites/d8_webform/web/modules/sandbox/webform/reports/accessiblity/text
-    pa11y http://localhost/wf/webform/example_accessibility_basic > example_accessibility_basic.txt 
+    pa11y http://localhost/wf/webform/example_accessibility_basic > example_accessibility_basic.txt
     pa11y http://localhost/wf/webform/example_accessibility_advanced > example_accessibility_advanced.txt
     pa11y http://localhost/wf/webform/example_accessibility_containers > example_accessibility_containers.txt
     pa11y http://localhost/wf/webform/example_accessibility_wizard > example_accessibility_wizard.txt
@@ -114,26 +127,26 @@ Notes
     # HTML.
     mkdir -p /var/www/sites/d8_webform/web/modules/sandbox/webform/reports/accessiblity/html
     cd /var/www/sites/d8_webform/web/modules/sandbox/webform/reports/accessiblity/html
-    pa11y --reporter html http://localhost/wf/webform/example_accessibility_basic > example_accessibility_basic.html 
+    pa11y --reporter html http://localhost/wf/webform/example_accessibility_basic > example_accessibility_basic.html
     pa11y --reporter html http://localhost/wf/webform/example_accessibility_advanced > example_accessibility_advanced.html
     pa11y --reporter html http://localhost/wf/webform/example_accessibility_containers > example_accessibility_containers.html
     pa11y --reporter html http://localhost/wf/webform/example_accessibility_wizard > example_accessibility_wizard.html
     pa11y --reporter html http://localhost/wf/webform/example_accessibility_labels > example_accessibility_labels.html
- 
+
     # Remove localhost from reports.
     cd /var/www/sites/d8_webform/web/modules/sandbox/webform/reports/accessiblity
     find . -name '*.html' -exec sed -i '' -e  's|http://localhost/wf/webform/|http://localhost/webform/|g' {} \;
- 
+
     # PDF.
     mkdir -p /var/www/sites/d8_webform/web/modules/sandbox/webform/reports/accessiblity/pdf
     cd /var/www/sites/d8_webform/web/modules/sandbox/webform/reports/accessiblity/pdf
-    wkhtmltopdf --dpi 384 ../html/example_accessibility_basic.html example_accessibility_basic.pdf 
+    wkhtmltopdf --dpi 384 ../html/example_accessibility_basic.html example_accessibility_basic.pdf
     wkhtmltopdf --dpi 384 ../html/example_accessibility_advanced.html example_accessibility_advanced.pdf
     wkhtmltopdf --dpi 384 ../html/example_accessibility_containers.html example_accessibility_containers.pdf
     wkhtmltopdf --dpi 384 ../html/example_accessibility_wizard.html example_accessibility_wizard.pdf
     wkhtmltopdf --dpi 384 ../html/example_accessibility_labels.html example_accessibility_labels.pdf
 
-    
+
 4. Run tests
 ------------
 
@@ -216,11 +229,11 @@ References
     git tag 8.x-5.NEXT-VERSION
     git push --tags
     git push origin tag 8.x-5.NEXT-VERSION
-      
+
     # Merge hotfix release with HEAD.
     git checkout 8.x-5.x
     git merge 8.x-5.NEXT-VERSION-hotfix
-    
+
     # Delete hotfix release.
     git branch -D 8.x-5.NEXT-VERSION-hotfix
     git push origin :8.x-5.NEXT-VERSION-hotfix
diff --git a/web/modules/webform/drush/webform.drush.inc b/web/modules/webform/drush/webform.drush.inc
index e22ea1212e..79ef5096f3 100644
--- a/web/modules/webform/drush/webform.drush.inc
+++ b/web/modules/webform/drush/webform.drush.inc
@@ -3,7 +3,7 @@
 // @codingStandardsIgnoreFile
 
 /**
- * This is file was generated using Drush. DO NOT EDIT.
+ * This is file was generated using Drush. DO NOT EDIT. 
  *
  * @see drush webform-generate-commands
  * @see \Drupal\webform\Commands\DrushCliServiceBase::generate_commands_drush8
@@ -225,6 +225,20 @@ function webform_drush_command() {
         'webform:repair',
       ),
     ),
+    'webform-remove-orphans' => array(
+      'description' => "Removes orphaned submissions where the submission's webform was deleted.",
+      'core' => array(
+        '8+',
+      ),
+      'bootstrap' => 1,
+      'examples' => array(
+        'webform-remove-orphans' => "Removes orphaned submissions where the submission's webform was deleted.",
+      ),
+      'aliases' => array(
+        'wfro',
+        'webform:remove:orphans',
+      ),
+    ),
     'webform-docs' => array(
       'description' => 'Generates HTML documentation.',
       'core' => array(
@@ -429,6 +443,17 @@ function drush_webform_repair() {
   return call_user_func_array([\Drupal::service('webform.cli_service'), 'drush_webform_repair'], func_get_args());
 }
 
+/******************************************************************************/
+// drush webform-remove-orphans. DO NOT EDIT.
+/******************************************************************************/
+
+/**
+ * Implements drush_hook_COMMAND().
+ */
+function drush_webform_remove_orphans() {
+  return call_user_func_array([\Drupal::service('webform.cli_service'), 'drush_webform_remove_orphans'], func_get_args());
+}
+
 /******************************************************************************/
 // drush webform-docs. DO NOT EDIT.
 /******************************************************************************/
diff --git a/web/modules/webform/images/addons/emfluence_webform.png b/web/modules/webform/images/addons/emfluence_webform.png
new file mode 100644
index 0000000000..2efb92a582
--- /dev/null
+++ b/web/modules/webform/images/addons/emfluence_webform.png
@@ -0,0 +1,124 @@
+�PNG
+
+���
IHDR������l�����G����gAMA�����a��� cHRM��z&��������������u0���`��:���p��Q<���bKGD�������������tIME�9.�x����IDATx���y��E���O�L9	W�X0��S
G8���YW�2���/��.�wE�etYA9E]eg�ŕK���@�$$�HH�����L�����\��SUOw߯׼H�I?��Է��z�*P
+������F��*�01v�e@��%���@'��*=�T���܃*�.@���`�'�7�`,0l⾤�����<������|,|���k�r��0���������cc�S�X�����s��K��K�r��@��|��u�D��a��{����߻!��D�6Nv��"���<�\	��q%X�:�,p0.�;!�`p+�U�X^�F�
V"P���cQ�$[�������2� ��h�NC��z���s�Vl-�	��`%B5��Jm���D6X�
r�<���5X.T#���gS|Sd����~���0/�<�JM~�u�Fx9�꼍�^��?��<X.T-�q�?�{�Dj��el
+Uw���4X.T�O�O[�Dj�:�����2\�+����wl�O�RRJ؍��b�3�����P�%�plv�H=y8���:\�����ˁ]c�;"),�N�t�9X�P�5�
+�4���سb5���.[E�O��F�+V��>��4�B
+�4�^�E�]A�������~D<z
+��\�]ªZ��}�o`�L�4�ݰ�>��.ᐃ�^x,pp2�O%�������Մ������T��D�Y��mTј�]R��FK�IsZ�=���P��my\����B%�k�K��P��C��
fa`ֳ��*���H5
+X�5�!�6`W�%�lj���g6=�ʪ����+��	�t[��ҵb\bO���n����c����˅j6��Ϧ=�R�qlm���V�T�KK�#���h�~؇�1�ڒ���.`?~��)\�_�Zy�O3c�EVb7��&L.�Z�^�p������6�D�
+��C���V���3�#������L�Gti����	�n��}	o`3>��Z�7��T��[?�����ӱ^T�	k]��U�j�fb�y�	\\��t�
+R���}��-�~���5�бWJ��e��Vk�+g�U7�GW�_bkv+PM��%
�	|	[�(�~[��Z��ؖ91���l�\�jR��{��c5Ў=��5���Eۓ~Z���7'b#�
l��"6���(T����c�����Z��l4q�WW�5�'�/X/bk�
+��-�=,be�O�{�]���_%�je�5}��Y(T2���r�����ggFM+�����Y��bc1�[�[@���q�����+��Ў�����`��u:q�"}u��F-��#a,0=9z�l�FG~��;�R�
+��,���
|�"�����Qn���{.PpI��P�$
W���.-B��лu:��*�2�dF�j�zt?pnBA �C���r�F"l7�M�l�5�J<�ۏ8�"�l���A�{B2�q�d�d�}P�����Ї������{�,��O�uj�ģ;���C�	ط��A�}1������O�������ZO������k߀���S��V�����C@K{Dd|���)T⛫c���	�L�f@kxᖋ�n�		�&�չ��{���,�Qk%����ẃ#��E`��NZF:�H�����Q�Q1�ݣ��c5%�zw�x80�H���U���xau0�R�{W/�u}%��:�(�R�c�l��vR�HR�p�~��΁v�V�c�TZK��Ë���!t:�H_��:ք��XE]_I,��[�=T���	uR"��
+����'+JȮ`��a�v��;
+��
+��
+��!�����i�
+V���+�]�`��}�"��l�F�>Y�P4x!⁂%⁂%⁂%⁂%⁂%⁂%�Ak��I�^
-w�O
+VD}�il�ׁ����
+�l����VV��A�� �lw�i�~�>e[`S�Zx�7�`=�<
܂-}�Y~m,.+���i�S�ね�|��������¶��j��/�jźy��N��P�e4��eئ�3qO�z�&�(X��;ʕ{"�c,P�[�8������=�e��,��0�J�d�B
f$ւ]
��*\a)X�$*�qX2#B1�b��/�p�`yP�K��"gp.
+WP
+��+;Te
+W`
+V�\���
T�!Te��o��
+�_
+V�\e�8�>vy�0�*�W�4:+#.T������y�=�E��V�+[G��]�!��O����6�]�!(b�Z���C�ʀ����c��
+��3�|Q/�l��z[�� l�E2�`ecW��؅����'�̞������;�.K
�؀K�����`�7�E^�[��L�]�F�`��)��b�LWw0[
+Vz�v�]��X����%+�-��{W���]�F�`��O���n��1��5R%+�wS�ݨz�`�+�v��ރ%S�D<P��[���?
+V:%�&�'vA$_����.@t��1+�|s#Tʕ�mɈ���S������؅h$
+Vz�`�ԫlk ��ʐ���;�#���J`�v%ɖ���:���_c�F�.D�Q�Rr���/�.K
z��h���\Q���
+p�w�������S���
\�� U������2�
+��l��zQ.o���uA��N	��d;��aὠn�
+VF\]��
a���KPk卂����w�p>�M`�Z+���څm�������kؚ���]�k
+V�\�^�v�!vy:��y�r�'
+���.�•���y�l�"�K��O���UޥX�~��T�G���P�`��8�M���u�5�g��������<*W�B{�Jl��`{R������{j�*<�X�������]{e9�upp:�al��B�Z�@J���+�v7w�`[��-��i�/ۅݔ�܎��}#yL�C�
+(Y���Xv3����l��}�{M���s���.�� Iw�1$+���X+3�}]�u�w�6��x��ד|P�"�+�����j��䋂�C
+N�Ө��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+��
+�����H
+�5����(�ͪқ�Տ+�H`B���x���ѕ��-�vZVh���*��S���U08�o�t;`�*��V�(�(��&)^�a��~���	��(�?
+X��
+�Ҍ�>�j[�^�~"�y���/�s��
+�%��o
+��h�v~��]���}�����ޱR�ژF7(:��Q��p�`�O�����j*�#`�����'��ޚ>X�B���L�]�:�|hQ�6h�`a���5�T��
l� y�`�����ns�Lt]���e��&�.D8�-v!�B��#����1ؽ?��+���n�� CE`�0L�W��=c���������l�
d�u�B�A���}I6^�4C��5{�^��]��X�y���Z
��
�X�	�����*�}@)vY@'pK�B�ES˹�ZYxx<v!�B����b��F���������c���\�y�`���<�{��؅�CK�����ؠ��*C���9�>L5����]_IB�z��B��X���uw3���n�V�)XNE��~�V�x��X�݀Vj�ViJ(�n�-�y/� ���4�p`�s^�:���[[�n`Y����)Xʕ��ޱ�y|�}`2կr���������*��)X�H�S{��jj
+��(X�PE�Zh�B�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K�K��
+�U�|iv[�"K?�������eS�@`D�{/��?�)�wt����勂AE���N�4`7�p`����$~v����B�a��c�����R��S�K�jp4�1� `[�}�u_�S�c�5������X�z@�I�
+�"PG��VjӔ/=
+��}-~�'�D��
+Xx�U�0��X�҆���L�W���&�ϽY���(�J��N�8������م��Š�+$�X�$B5	8�*aBU68	����Η�)X~������^
+\����+�ڨ+聫�����b��
+��7��@�N-V�\���"�*�
+�8��ޡ��3+C�����ú-�^0{[��� �N��V�0p2�}o�
l�V˟���뎫���s��<���؅hd
+V�N��C0�<0^��
+V���Xw�L>��J��F�;%vA��
+��
hH��ll
�=��~��Tw0{�Vr�U�}�g��Mp0<vA���^+p��F=:��9v!����p������tu��`�7��W�����h�����.DJӰ'�%#
+V
+��T����m�a��H�B�A�&��B��dL�J������c)vI#T��&�.@&��.D#Q��[��F�w%%+�p���"���dD�J�����Q�Rp����GE��z�1���=,�]���o�.D#Q��{[3��=���)+�.��؅Ha-�H�OgK�Jo-62�.vAj�2���dH�J�}���
�՛{��"%C
+V6^n�]�tb�
+��}��Q����X�����C�W�S�2�*�����R�N�R�_ɘ���n��z5vA���}�� �J�ʈk�.�����Y�\`���~(X�Z�m�}��5��
+�?
+V�\E]�m������C�]�=vA���1���=�V�.OBp!��Vk嗂����?��p�C�Mt]��偫��Q�OD,�_�P�t*Ta(X��
+܃��8�=Z�4�i�R�`y���O|�0s
+WW���
+N��4���W��g�?�z8�*�Z`&��I�*���h��m�;���Oga-�)�����],�������|L�C�
+�\��%�����Jޅm��� /�X���7a�oϓX�M��K�� �l��r�:���x oOb#��T��ħ`E���`��@�ӵ��䃂�
+GcѨ��
+��
+��
+��
+��
+��
+��
+��
+��
+��!�U��Y�`ub+�4�����dEB	����4
Uv,B��dEB	�Q�ޱOV$�"��H<L�}�"�����-�"��{�61/bKi���D��
+Lu�"�
+�	ub"�`u0�E!G'��O$�D�F���-�v���ΒH&��T�"�E�X`�P'&R�>̧b��P,��t�h�]	��X���"6�<Ԭ���VK��/б���������:K{7�ހ��.�c����
+	x���܇�t`�@��3���m8�2�N�W�%��:6
+��/�����"v�uk����l�pI��a;f��G�T�A��:���O����	��x�'�R�mx6۲3�q��j�O��<��������cu���G��S�������Z���Z���zx���걋����j�$c���
+�n`
�`���]���y�e`��%Yp�h�߰�Pz-����p���3�Y�7E�&��l\���y`^y��d�V��;v��Ll��%5q��|
+��W ��J�/��6����e�?A�$Bu
+p�C���Ĝ��<�������C�p�иzR�B�}�M]Jzx��
�����6�)�I�O��K�Uh�U;�Y��tXv��,��;���A���02����>p����T�"�Q�z*��/�
+p9�Z-��obC�
+�����d�R������d7���z�t`��nqe8��D�e��c�oY�IT|���F�O�}�F����2p"g����;��ˀ�q����*5{�hv
��z�c����mݢ(X�˜�V�7���+��X[A�o�t�'GaODL'�l��<��������;����`�Ėƾ��5�]�C
+Z>
r��
+�Ě�=q�;��ú�p	�]���vp�3�G���#�,6JSž���A��B�5�vvĮ���֧��4vA�1�ݱ���?\�ŖH�l�`�\Y6���t/'�L��rd��bj�V��G4h�Zh�|�*"��J�/��J����j(s��a�!�}V"�-����ܠ�r���|Ե��8��Ԑf�p��f�=�#�@z�[<����6W3���M6�
+�K�˵�ÓC��Sս7J�
6��W�	`p"�H5�E�z ̽�RlF��g,���4�����\w�gb���'�`u|n-���`%�;8�\�x`u{.�65���W��^Wb�RD�]9T�A��Mk^t#q�����rI�[���T��f'Z����~�\R��5w��R/Uq�u��g�	EjՃ���B?��Z�m�����s\"I%��u�$���|,l��
+�h���H
���6�X���{y*3q�u4�U�j����MQ��<i��q�D��>�#��4���E�������#�ւ�;hC�^Vy�ڟ��ݾ�C	�@G��	|�ٛ���Ks)��]\�-�d���+�$6[:�4`*�X#NG7������ �]����X�j<����Fa�B�G�
+�i�jl���o�^
+/�Zm������h�L�Y.�;�`�^�m��+}Ċ�[��lc潱�
�]NɕuXx�9�[�n����k����xu������a����6m���*�lq�9�C�C���?;Pe�	�F۸%�u�c��]�QƩlh�F���zՃ��Z�G��`ݼ�X7�-r�2�'���UȾ��n�v�؃
�:[�8;c��^����z���q3!�`=�M�����ER>q��L���%tEXtdate:create�2019-05-02T14:57:28-05:003H�8���%tEXtdate:modify�2019-05-02T14:57:28-05:00Bk�����IEND�B`�
\ No newline at end of file
diff --git a/web/modules/webform/images/addons/hn_react_webform.png b/web/modules/webform/images/addons/hn_react_webform.png
new file mode 100644
index 0000000000..ad6e8aaca7
--- /dev/null
+++ b/web/modules/webform/images/addons/hn_react_webform.png
@@ -0,0 +1,15 @@
+�PNG
+
+���
IHDR�����������.Ч����]PLTE���������������������������J��������������������������h�����9��������v�����[��X��9��������y��[�"Z��IDATx��]���P�	%�ϼ�c^�	B{���U��glh:~���K_�җ���/}�K_�Ҟ�Jʲ��<�[+eY�]Y�i�ʊWLB�C�W��5vm;ĝ�8��/fRG��l/D�L}��H56�@+K;�T���Dُ�~i�֊w�Q�[i�b�Q��s���s˩:���p�n�\��ֱ�V
D�������yI��]g-=�k�2.�M���=���rW�@d.N�Z8�C�Y�'��m{5EΝ����K�.���k>���~�U�y5���$2��?�v�/�k��Km�������{��i'�T4��u6�+cW`<~){z`m;o��(��}Ӊ�����A�G7�x���l��Ư����h�@T>�8����_��T�,H���5=�^!J�ls*0��}�Ľ���G�-)��l~���r��J��C��:^���Q�7=[J�#��R�S���#��-���)u�����;��	����
+���I�M|D�F�S\�g�f��Džp���[67t���H�&�y�\̅��5�_��/+����1c�4=}�(�|
η��6��ž�U?_N/�s1�p�����Ձj�v�E$��oL�Y�7zn�7W��ۥV�]"���7�?f8>�ӏ�fޓ]0I�dl�Ez�vl�v�� ��u�52���ٓ��Ǻ����Rڨf��ĸoл��Da������Tަv�?�z�*G+O�&��ڦ�u.۰���:����r>��/;s�6eS�8�&)B~���(�s
y�r|Ú>�['G�aq�Nx�I*7�}��5+5lU��or�ʹ�z��P%~��g�����3`�&�gy�Pm�p`�H|2��OI����9����m�;C~;{��P#�����Q�b����EI�.�5y#���P
+[T.P�}��$�렸�_�-&$�D��E~a�LL�:�g0)x�a2��&nDq?d�㫍):&��
+��90�}�E�<0�~}u�1����)I��h�6�i�_QwUMAd��U{�H��b���(Ϫ�W!��2Z����%2-#��P�3�s<w�'&�wf]ю�DY�ڊ�'i<�i['>���W0�E�|���&^���\�����OȀ9������3FuS�|ijf�M��&���������K�N��{��Ӗa�'�A\_���t�=/�E(�����Uל���cq��{]?9Ǩᛴ�ʲL�Y�	4������ggb�<nڋ̒�tj��=Ul`TI�Α(-�5.�y~��,3��ͼ���!?���C.�s����A�v]�I�?�^�R�|��+�3fN�	
+�Ae
^�l ��I�����S�I��3Nh%6��36v0���=��t�p�k��2ި�-�C��XЪ/��	�KrbƇ�P��8�ێA>�0B��M����^ .65���I��/-���s
�Q������Ye�1򄥶)�)%�׸���t�唸Me�{E,3��&�/��n0	*Î�>*�E�,F��C#�lPe+�/��,���j�P�`��1`V��B��e(�^�
$d��XKq�	iѲ��A��w��a+!�>���l%c/�CR��žDL�V�{3�>���
+"ve�A!�!�HĖ��a����a��X;��9���6�v�G��ڂE��wB祱��Q���t��oג2$���������x���13���z-v����!�̹���Fv��
+�@5�\7���:_ hkB��VR!��p�4�F��Ñ`?���M�Q��/�+�A�5O{Ԙ�j�@��D�7@�����\)"�K�pD#2零�����7a�q�w�q���"�ɦ��[x�M���zG$W�����As���Bg+�֬�*�T܁e��s��.�5�,il4�5r�Ͼ�f��I`�d�X;���ͤf?�C�w�]�#i�R�Rp���dC��lg�'�N&E�A���l����i��.
R�bA/>jQA��b�PE[�Q�Чb���c��>�#ذ\isy�ڸQɏХ�Nu̸����̼"�\��J��e�!B��4A���������+>v�
+3�r��wN��a�|W�n
�2����d��g\J�"c�,Aa5Q��y/#�j����Y�F
+�+f ,Cct�p�̬�{�O��:V){��3�mq�%�G^�e+Ė��L`��JO�Q\lo4����������R���T��O�����8�)��6�]I3(Ӟ�XW��rܗZ56I�
��Zi�L4���W;�e��l�,-\*���l�=ّ�ˁQ;��L�a��81(d�`�~���M�W��xv�(-�ߘ�T�%�v�����n�A=*�8��۳�.�Ʒ��h�R5�>0Vy�#iW��P��'^/���ɱBf�3��܀-�z���Q�`�MA��]�.�xXm�w�4rۀ��U�'����P/l���D��=8���d��
�Y^Şx�p���F�z�v�S[G�;nƉ��7��g�A�j�;�V&Er�(-W5G�@H!�#�'�m��"F��"�=ł�r�A�*��kL΂K��U���;vC�w��7!�ܲ�!���%iĈKh_�=��U�Q4�!�ҥ&�<�	դF�$u	�j�la��E�%��-��ci*5*ug���O�M�Jl���!��t'P+�G��ri���� �R�
+�w`j30i�#��Kg0!���^A�!]t
m����`�P	y���J7S�6$�ĸ]L=C�d�k�*��R�2Ys���q���D��m	�����2�V�V|��҉�'F���DqL<�
��q��;��$V�Մ�Xs8�-l��xى���<�&�㪕�/�hc���ut�$�qR+E&�hdo�O��Z
+[�*�e���+w6$��k!q��l?<|���!��v��΄��J+���3���=�]�a~�U��Xo�^A��&&�a��Wm�d�Y��p��݄��mG���v���w`�}��M�5:^sAO��+y����������x����^�u��Y��]�#���������Hs�S�����,�t)L���X�q�
ǯ#/m"^�˿`և1���*?`ym������H���,^���O����������~��0x��D^uE�����]N<�m-�Pp�Į��ړl�rȤ��1�|�	F��|IǢ�圉��:�xz����!qQo{�m�u�ǭ��<Ru�5V�u��z�>(+\Y��'�gJw�L����G�����L�.a����)�?�ա��.�+0�vY�x��6pT�X��@���{��nR1p@ټ�>JFϹ�-zr����l��$�;'�X��������u���'(�{�(�G�av��Պ�q:�+HX�	m��̛��k��x�#N�97���Br�@?!v���5N!��X��9�����^�CJ���%�¼3H�լ�u+��=a�V`y-Ǜ��5"V�N�
+��	�O���!=���כYZ:"T����]����d=�9�w����B�ks
�J�)Ǎu���DžD��Q��=؟5��@�Xa�6}���ɇ�,}��BFE&o�����@���'m��5����A��<����.LϏ�B�ꬣo����5B�H�'�r���'��<�����N@e�Y��.$�>MN���7���ݎ�)$Ӻ�t?ǁp)�3�v���{�K�E1���$G�-��C
�po��b�y���("i$���%ο���&�\b�����Uv�\���uj�Z���z���$<r逩�?�)݈O�=�x<�yy��b9�/�g�)4��T|�i�g�AV��M�%�(��@E�{����L:������s�E,q�Q�W�S�傘R\�nr���[��_�A��^V%�����F������U��4Υ��!^h�a9/#迫�- ��@$(v(���=/�jG陓K����(���ݕH���E[�
+9Wϻc6P��P���g^��c��7j6���l�.1����G�i��cQ��'��|BU�������~���`k��_�}r	�YRvuW&y塗gIW�邶��5r_�җ���/}�K_���-��ȱ�������IEND�B`�
\ No newline at end of file
diff --git a/web/modules/webform/images/addons/react_webform_backend.svg b/web/modules/webform/images/addons/react_webform_backend.svg
new file mode 100644
index 0000000000..37aa217394
--- /dev/null
+++ b/web/modules/webform/images/addons/react_webform_backend.svg
@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 106 28" focusable="false">
+  <title>
+    Gatsby
+  </title>
+  <path d="M62.9 12h2.8v10h-2.8v-1.3c-1 1.5-2.3 1.6-3.1 1.6-3.1 0-5.1-2.4-5.1-5.3 0-3 2-5.3 4.9-5.3.8 0 2.3.1 3.2 1.6V12zm-5.2 5c0 1.6 1.1 2.8 2.8 2.8 1.6 0 2.8-1.2 2.8-2.8 0-1.6-1.1-2.8-2.8-2.8-1.6 0-2.8 1.2-2.8 2.8zm13.5-2.6V22h-2.8v-7.6h-1.1V12h1.1V8.6h2.8V12h1.9v2.4h-1.9zm8.5 0c-.7-.6-1.3-.7-1.6-.7-.7 0-1.1.3-1.1.8 0 .3.1.6.9.9l.7.2c.8.3 2 .6 2.5 1.4.3.4.5 1 .5 1.7 0 .9-.3 1.8-1.1 2.5s-1.8 1.1-3 1.1c-2.1 0-3.2-1-3.9-1.7l1.5-1.7c.6.6 1.4 1.2 2.2 1.2.8 0 1.4-.4 1.4-1.1 0-.6-.5-.9-.9-1l-.6-.2c-.7-.3-1.5-.6-2.1-1.2-.5-.5-.8-1.1-.8-1.9 0-1 .5-1.8 1-2.3.8-.6 1.8-.7 2.6-.7.7 0 1.9.1 3.2 1.1l-1.4 1.6zm6.1-1.1c1-1.4 2.4-1.6 3.2-1.6 2.9 0 4.9 2.3 4.9 5.3s-2 5.3-5 5.3c-.6 0-2.1-.1-3.2-1.6V22H83V5.2h2.8v8.1zm-.3 3.7c0 1.6 1.1 2.8 2.8 2.8 1.6 0 2.8-1.2 2.8-2.8 0-1.6-1.1-2.8-2.8-2.8-1.7 0-2.8 1.2-2.8 2.8zm13 3.5L93.7 12H97l3.1 5.7 2.8-5.7h3.2l-8 15.3h-3.2l3.6-6.8zM54 13.7h-7v2.8h3.7c-.6 1.9-2 3.2-4.6 3.2-2.9 0-5-2.4-5-5.3S43.1 9 46 9c1.6 0 3.2.8 4.2 2.1l2.3-1.5C51 7.5 48.6 6.3 46 6.3c-4.4 0-8 3.6-8 8.1s3.4 8.1 8 8.1 8-3.6 8-8.1c.1-.3 0-.5 0-.7z"/>
+  <path fill="#fff" d="M25 14h-7v2h4.8c-.7 3-2.9 5.5-5.8 6.5L5.5 11c1.2-3.5 4.6-6 8.5-6 3 0 5.7 1.5 7.4 3.8l1.5-1.3C20.9 4.8 17.7 3 14 3 8.8 3 4.4 6.7 3.3 11.6l13.2 13.2C21.3 23.6 25 19.2 25 14zm-22 .1c0 2.8 1.1 5.5 3.2 7.6 2.1 2.1 4.9 3.2 7.6 3.2L3 14.1z"/>
+  <path d="M14 0C6.3 0 0 6.3 0 14s6.3 14 14 14 14-6.3 14-14S21.7 0 14 0zM6.2 21.8C4.1 19.7 3 16.9 3 14.2L13.9 25c-2.8-.1-5.6-1.1-7.7-3.2zm10.2 2.9L3.3 11.6C4.4 6.7 8.8 3 14 3c3.7 0 6.9 1.8 8.9 4.5l-1.5 1.3C19.7 6.5 17 5 14 5c-3.9 0-7.2 2.5-8.5 6L17 22.5c2.9-1 5.1-3.5 5.8-6.5H18v-2h7c0 5.2-3.7 9.6-8.6 10.7z" fill="#639"/>
+</svg>
diff --git a/web/modules/webform/images/addons/webform_calculation.png b/web/modules/webform/images/addons/webform_calculation.png
new file mode 100644
index 0000000000..aad1e47dba
--- /dev/null
+++ b/web/modules/webform/images/addons/webform_calculation.png
@@ -0,0 +1,15 @@
+�PNG
+
+���
IHDR���d���d���p�T���	pHYs�������+���IDATx��k��u��jY��B��E�D�YȂ���pD/؂��+�D&�*����E`QaR��v%*�0;�yZ`�hnm�+
+����6��9�0}��h�3+��������?�ӏ�==BM0�����3�f]�o3����������^�T%0�L�>+"=�M:���m�
����U�@�1'�Ƚ��*<�GT�%��>_��t�c>��骊�D�N���B��a��������Iq�l��w���]�ٮ���(U Ƙ�"�4�ά8;�y3+�wX�#�ȬBK��Ϊ\9u�P�S\����dL)*p�9�4D������U�VC���_פ�8n޼yk6o�\�����3��:�ɴ�Z�Ÿz�ė�#Z(Y:�PDA�<��ܢp��˒�
+=�#�π]�{u"��n)z�'�H����2
+H�6���:lHL���
+�u��>�`������P�2��u�yy�8h��>��^o�ȅq���??O<��%i����i�Yn-��Ԁp���uݑ��o���\�#��f���[q[�$�u��%�01(8G+Z ��n���|o\w�@s��.��܏_>rh��on=���C��q�l4�1�kj�EQ�@Dd����KD�"|o,���uɟ/Z3�=�+��g�W��2N�5�uȽ3W��8�bo��yʓBy\f��8‰��qc���8�"`0�������/�2e��+��3���("]"rA
_�h4|�8��M�5��[�`p��y:���xG����}'.-��z��_7?�������Maמ��Y9�s7=��_�'_�<���MV�� �~F�	k/���>�����K<�[688���w�ٳg	@��X "3�]{��Y�y�����#"r��xO��'��,�5������{pjRz�c�O>������8 �W�G�����0-�'ᰢ(\ E`kN����6zzzf�Z�p���l6g4�Nb���V�5#o�k���G�x�;�1���4!�"�m�=���hv	KO:3�����8�ׯ9iλ��7#���p��凊�U`��8+���O�+"��
+l��ș@7�ֺ����7��V�u�x�r���0�ت�����}�\D�&r��m�.X�}\|���<��nn}�9��ҏ�>�p��\���$��������R}HGY�r���-�#"��&���y�M��G�=ϻ����oT��<�[։���7CU/'S	�F�Y��v�=d�_�n��8�s�6.Md�蔩g�:�`������+���{7������ݽM-�UPƗ�;�uE�U�^�5�=��\���<�.��i����dt�op��m��xm�k��q.�<oAg�A�����-���o��}�����������̓�j�z`���f_�z��ԉn�N�I�C�Y?����}��AS�S;Dnu�Q
�$"�	2�N��ہo��<����<�q���f��^.S�1�����^�d�V^=v�;�?��7���ү�1ut��C�O���6��%���z�"
+m��T���u�[K>400Pja�퀅��������=�1vtϔ�+�eΫ���?��O$���k��׆I��hx�����L^�)S�׹T���-��j��Ed���<�y�qfa�;����no=ꨣ�"���	}��8'bw��������Xwww��y����y�H�՚�n�wGd[;_P�-�v{G�՚)"-e��y/�Z�i��
����&`��<o�MC��n�XΦ�y����(S0�&��~�x?o:�>,�/"�Z�VW��0"�(,�8N/p��]8>>>��ݽ��K˽0����1���ʞ "+�L/�q`pl___CD>���5��������8�2�;���i�ʝx�u���!I��6l������0����v:��'vFۥ�Q�j��yލ�����nU�f�{T�!"
U=$��iY�q>�y�+�Vk��\�y޿�{�$���T�]������w��K0����8��͏��"��y��n#�/��p��8c�|�	��H�a������	8†m�1�U�qn��_���	]?a9|�G�;��ݨ�߱O{,�R_VA�"x"�x7� p6|\�Ñ��ٞP���l��`^���Vǀ���T��w̷aa������v���!��Q%ud*Hԙs�����t`��y��+���QL�,���Rոx4Y����/������
+qnϰ�`bE�}�%�LȳE邪<��hC���p�|`��y_^�M�Ӫ��v��t)�����v�?�q�u����K	��jÆ&���96lLU�o�ۯ�O�L��[Dv�^������l4X���7����CCC���u�KMÆD�8��2�;8��E&��&�����jNݸ��j�G���0��2+��իWW]v���:��tp~E{D�MsF��B��5R;�1毫r(�i5��:����Ÿ���5�l�����������|���z6��V�ڇ��Q��<]u�4�|��Յ�ǡ�>$6~���ܣ��V�,�=Rq��8 ~kO:�!_R&�yф��HB�S��#MgYEP�U�<OV�L��Jӓ��:����7��������k�㚋$�4iq�:���-+��Q��J5Yq�U\��F3%jx�q�7~VF��H�WUGTj����I�&����wW���Ȳ����(�d�(����<vIdG|(1
���l~�� "�4أ�'�������9�z9[yLU�l�`c�^�;PՆ�N��������������c�""7�E��M����Mi�"�����/��J�x-@U��j��c.��J;��=��,�D���TF�
�+�!-��>%"_/�m�zOQ�4��F'C!�1b``�օ9c&Z��pwd�&q6l�����Q��uQTZ�i�r�m���ϩ2w��]�;.���n����/�'4,��n�O�_��i��ŗ�?Q��%ˑ8Y�eP����θu���Q��̽$ԺQ����G����dX�[P90=�'U�n`Z���&��eE$V64j)͝%��;'��7�]n��pQc̅�zz��>�sV	��lq�n������������F��x;t�<d����$�jp��\n]�:��Ƙ$�g
U{�~��ҙ�m��]Ƙ�Ǿ#��y�NV�4O�~�e�9�Bp��\\'�g����v+TuEQ�s\����KD>���M'�H��*o%�{/)<i�S��<<In��:�b��C�jJ��m\�,�|Q��ґ�I}�*I&.�Ug��&�LMϲ�YxKf�uf~��i�[�'��\ q3�hx/h��-�;�Q&��f�cU0
�V�FY��,��|Y�y�E�����K�Ym��n!x�/
��3Dd��S	��L�Fp�M����:8]Df�
���a97��3���i�zd�3��<�e�12��	�6�ًƘ�z'�8��h3���|�uݡ�8z�騽1��#X~ε���	|�cc�(-J�!1�y��ǀ���i3�"`±�1�{����\�a���+�ll:,�����!8O�:=ޥ;���j�u����0pw�'w��;�t3�{�+�/���P�{X�ɋ8E������WI:`o�T[�����W�H�DŽ4W�>�!U�Y%��@�&8,��٤`���n޺��J��?w��:��v'Dτ�6�:���*�aΨ����u.P�>�7zm�N.eE�����R�XDNI�;��N��9AGQ��u���Zn��6�	c�	�Q���Ƙ�D�d�>��8�CaX�r,����ܤ�r��c�7�G׮]�:A4�L%�A�R�7IRj�4`�1�Jyp`` u����ߣ�Fp������TՇ�1W�eM>�=�ܦ���U�y��m�
+I�����]���/	
�ܛ�~'���}N�jpBP��ʘ�V*�E1k�	��C0c�K�\��=@O��-|�K���oڿ}��8�p�t�����t�q�W�b�zD�8*vsgq&U����Wd����"��E�w1).��d�8�ƟL��J}�㚢�����u�T�f2O��u]EGԽQ.��<�\��(���!NG�
iv��Q��Q.Wxq�0�C���Su$=MQI�uE1Y��Tu�����Pg��\b&�)���Uݙ6J����>Iy�3�0|�O)�������'���3���8��u3���������]�����K}�yݺu�.�ŋ7��|U�SDN�a�fY
+<��}Cc�<�v)��<
�N58��}E?�n]/�H�; ln8��W3-w/�'3f'��������ZA�i�3"����?�`�ADV-����S���E�r���3�}�haX���}Rj�(���T�z)��*w�X�5qB��D���,��h���Re'���ʠn�Έ)�MR��:&�D�:��	��3NG�	^��(�d�qz�l�JO�%&Ӫ4���!U�SO��Yn�������D�>��zt�'����qbj�>�����ɋ�F�Ed0� �P�/�=��`��Ih�m8�!�+����One������>mm(jwSU��)�A
+�h����#�,ҙ-��5��>ޮy?��&�Z�#U�~c̜t�	�sT�~+���<Pd�ަ�^`A
+�	���Px��󐈜�t�&p�࣒��E[�FW�31�?
+<K�עJ���<��ȘuϤ~ٓ��%e��rnp]��<�;(әݬ��yih�|<%F<���D,�ى�E��L9�oέܢ�<d�H�/��.��N.�sM��H�Kґ�.�x��U!�ګb��+"O3��N@����C�P�S\�-ԡC�����Y�=�'�z���]��9���cd����Ie�б8�u�R�~�T��1'�Ƚ���\�OQQel��T�%��>_�(�)e~��_��1��]�`�x9(�\ބW)��:��	���']��Z�(�YE8;�:8�`>2SD����m��"�9ɱ��#g3;B���&�!`�뺩o���QW����6����IEND�B`�
\ No newline at end of file
diff --git a/web/modules/webform/images/addons/webform_rest.png b/web/modules/webform/images/addons/webform_rest.png
new file mode 100644
index 0000000000..432cc9605b
--- /dev/null
+++ b/web/modules/webform/images/addons/webform_rest.png
@@ -0,0 +1,55 @@
+�PNG
+
+���
IHDR�����������7����tEXtSoftware�Adobe ImageReadyq�e<��hiTXtXML:com.adobe.xmp�����<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.3-c011 66.145661, 2012/02/06-14:56:27        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmpMM:OriginalDocumentID="xmp.did:04801174072068118083802FFF5586C1" xmpMM:DocumentID="xmp.did:44F053FA7B9211E4BC6E8825DCF2699A" xmpMM:InstanceID="xmp.iid:44F053F97B9211E4BC6E8825DCF2699A" xmp:CreatorTool="Adobe Photoshop CS6 (Macintosh)"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:05801174072068118083802FFF5586C1" stRef:documentID="xmp.did:04801174072068118083802FFF5586C1"/> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>xs���Z&IDATx����$U�7໒� H%,�H�EDA��
+�1�"����.���;*I	��(��)�fq�?���,�����ܭZY`�LwuwU��>�yj	;�s����շ�4gΜ��T�QZ���6����� `��6����� `��6����� `���
����� `���
����� `���
��6�� `���
��6�� `���
��6�������
��6�������
��6�������
��6����� `��6����� `��6����� `���
����� `���
����� `���
��6�� `���
��6�� `���
��6�������
��6�������
��6�������
��6����� `P3�F�s��������4�̨�F�@+��iҜ9st����g����2{j�VW�����9ߟgh@=��
���F�����|����MfOMc�P/�`4�̇��Q����q���YC����tw������t	�>��������D�=���6@�MI���{��_n�z���V��w��m�b��JQo�&��p�����g�����_�����N]�=w��k�8��5���.�zp�����mc�	��?FM�=5ݧ{���6@=͜�����Wh@﹃
P3�F�3b���ꯢ6�=59���;���3�ſ�iԞ� `P�6�����%��E���l��o!��� `����f�
+�����6�������a}H;l���x��<��/9CWl�A6�����h+��
0pʻ׻w��>]w�oҔ)St�^Z:jղV��Ϗ�Z����V�Z1j��r;)j������o����%���j75
�_��:���`���]����.��s��W���绣�o{��*��wD���y�|k�-e����[������Kj��m^����vݨu�V/�kD�Ug�p=ԡp�-��d<6��J���}Q���)�oQ/���l���?��
*'`ӎ%����<�s㨍��X�qy_����?8{��;~0H�f��垨���~���뢮Iŝp�����e�3�򸢧Dm�:����w�E�6y��~Q'�8<B��iY��2h��qԏRq'lZ�fԶe�Ε�Z^[�R����y[��OΞ��r�u˚�X�����b8
+�,P�;F��S��Z���i�٣K�.��w�/�yh���-�9?LyyԷ�.N��\~������&�=������w��
�[�|�<��r����/G]u�
&�`�����n*Ɨ�q����=�F�Sc�g�����1�@��O�ޚ�;�7F����%`ӟ���W����O�zV*����}�ô�&OG{`�%���Q[h��M�m����F���}�5m$m�:?s����]{�.�|GԵQ?�z}*RC��!���R1��7��M�L�Gz|~x�]�=�g��T*>Q�X��Z"`S_��p[��I��F���}��������;g�{��z{y�>/%�H�����QH���'h	�2\�eˏ��9�u��*�M�M�x��D��wV��uC�̨�h	��Q�䵼5��?�O�q䲨o��څ�=P��<�:ϵyt*�Aj,��J���^/J^(c{j+/��è���6����e*fYS;�1��ؚ�&S�A����~ur�j�!`S�������X;�9���]ܩ�av�xmC���Q����F��
KG�'�g��{
4��T��n�ņ��CB��<td+��iM~����>��v@�LI��bA�������4�֩�q$ϩ��v،�2�/���6�h�� r�?ε�4S>��g;�m�C�fѶ(ߕ�Ӿ�f�62w��=�R��uE{i�T,�~d26[��&E�9�'Q�k�6�uZx�-�<
�w�e�l�g�/F������0m$�,5k��@�=3��j��=趌�*�Z}�����7L��,Z�D�+����t�KR1nj#���R�%�'”}�?f�A{��Eo����S}��ZP.������g����^�����EM�
+���kΈ��V@_����.6��'�!�T~v�Z>��Q��
+�?�F�Z}P�����գ.O�m쾒�@}+Y��Y����þ���ؕ�w�K�M�}�B��p��Ԭ)��	�62�c���ɏc��O�
��B����t9W$c����J�3%V�)p�]
+}��������\����ՠ%�'�pw�����iQ��
+�i��&w�a|���P���Z���wf�Z!`7E�������[�$��}��=~�G��з��:7K�#`��1���0�:?0tT��9\��[�]����g����z�6�@�K�?��Ʒ�������򐰯G��v�u�6@�+�|����y����q�{y9��R�̆$`��
�0P��$�D�9�P�i�C��7
+?�
v],�����o�9ϊt�=�Ш��A����P�ӴƇS�D����źv=�3R1d�g�]o�2������?�{�#�B^(/{]Z+�^X;+!�����Q������H���?���
v��짒q�0H����?/J�>�����k��Q�k�i#s�L����R��dijS�
v��>�
0P>e��b*ҙ��c�4s��5p|�*���a�Hzjlԉ�yy�d3m����%�B�N�-_o�&\��->�\���Ƒ��c�TL�0I+�N���
��Ϩ�R��^~H�kZB^�Lmx���w�a�^��U'F]���4�3�^�
�7iʔ)�0>yu�c���n��4꒨�D�fttt��Ъ�y.��,�`_�=5�Hh����IyV*����k�7n��רM��Њ�"c,�/�E�z2ȿnrx�q��e]���B����y��?�
+�p�|��Q��z^�w+����:�>z�V,��=>���`c��/�I����Z�q�ؼY'�e���=Ꜳ�5ϊ�++'��==��T<�r�V,�1؋�n�z�}?���S�)9\k�LJ��x�ě����ɟJ^���Z�}�nњ�Y!��� `W!��6t�?����4w0NOŝ
����tb�>�tA��{e��C������D���	� `�#@�ӆ���<q>.�Q����W(��1~ώ���
t�]Q�O�'�y!���Gw�Y�ޥ
v;�QHt�eQ�O����y����-��11�zd,�8�
�'�G��ɘx�Ey��7hC��v�zn�7R1;tݴ���TL���=#��m����<�s�T[���t�ҩXg{�N�^wR~9OZ���B;����
Z�r�K��R�IT~�<[;:j����A����ߨ
��T<����55��ũ�{��=-�%�@M�%�F�OV���R���-?d��6T.��{i��S��"�!\/��t�GF?]W����e�Z���b�r�qq��z����I��I��
����J��|s'/T��o��i�֋�]�񘒊�:��S1�zL+��i#s�:\'*ut�uEm�fr�>�|h��j��x���2j�T<xus|�0s���]��j�se�~@+*��`?^�EY>jm��/�_��hu3md��{�DG�-�;Y��<�ț���,��6؋�g��6��Ǽ�(�_ZA
�u�����e�1��S�*�J-���9��c�^u�VPSo��X:j�x#��6Pcy���jC%���h��� ���U*����6PG��X�w�DW�^R���Rq��v�����������ؾߤb�3��<tam�'�bU\��?�b.gڷ�\)`/�Ȫ���K��i#鹱��]��y�6PcgE}Gږgz�6��[-��ж/F}[�i��CNԉ�[5��@����]����m{i��=�<��q���'�#��;,C��
��@�]�Ymh۞Z `�o7-h�9Q��ꨜ�y�N�L~�Ŕh�݇R��#���ڍ�A����=yE�#��;-j9m���K���7��ֆ���v�u�p�sa�﵁:�P������X�K�Sg�kA۞�vf!��}\�i�^3YQ�N6H�"?PW?��\�򜨥lvЂ��y���j��oUm��#��㴁;Uڒ��
������;�g�]h��j�R���fo������,m��.���6�e{�m�<�Ԏ965
�+��d���}cm�
�ԝQ��A��[�l�m�2���@
�;��jCmM�:!B�$����ׂ�����ȠlKz��B-�n"�m��u���N��j�d�H;�老^\���-�f�:?WqzJ�6���p������
2��=q��Z��߲�D�B��wEm�
������j�b-���ڱߖoku2m$m�#t�q����ʸ��Yv��ұߖ˴���|.�CC�֍����b@��
QԆ��O�������P��7F������7I�j�u}%�"�$[�f�nM�
+��s���G�D��rIm�f~����=~�#�Ɏ������h5��(3Q4ߓS�I�ɏ��-�����
�)
+�q�P�F��c���3c���
��ϴ�-؃��N84?\��t������^���6�[��Ҟ�k5pl�c����o���
���[v��o˯��^���s��v�ʫp��xY��5�����=8�q̷�ƨ�j=����T��kO�z�6P���K���;�-�ǎLŃ���wƛ)��'s	�
���e��g"pM�͡:1�
+p�*W��=�K�n�5�-��Уp�!�T��10��:Dpݓ��fX��޲�h=�����a�|(�\��
���Q�҆�=Z���Y����n����R}�N��N�\��.ێv��j���6��ś�Wj�}r��]_�8��r��M�^�ub�gu\��.���k�-Z@��Z���Nr�>^p퓻l�������6P�7�t��
��!`�O�I����q����u��9%����.����X�;��.��
bs�N���E}Xp�kCD`1n����y鬨�t��xK'�h����C�â��s��˨/���!`�twh��i��|H'�-��\������s������q��6�6���з�& �;=B�$��l��D@zFlf�-����@�x0\/�����
Z4��:�@�h�����@V�:I���h�i#i���T��q<�T��p���|:�jT��q `)��8m�BkG}D�8�F��ؼB'����z�6�60H�z��|R'�<�(ύ��V�60(Έz�6�AyV������7m$�!6��]��8�v�@��9\o�cu�.�CE�4� `���欨u�.Z7�dm�l��#�Y�@�o���@��F��-b����N��p]m�l���ұ9'jݠ��8�<۪���
4�̨�h5�gy�6�6�X�FҶ�9\'�����L�hb�^!6gG-��H^����%�h��Fm�
��VQGj `�1m$=/6�5vx���l��z��|Z'h����8^W�
+@��u��� �m�l�����7���:A��6�ۗh `u�y��ct�:-�ߵ���:��<%߹�j�4��� `�qbԓ���=�(�
��
�\��}b�Z��������@/���؜���Ή�zI��l��z��|!jeݠ�<=�����@/��6Ї�o ��@��&���cs�NЧ��<Tdy��l��z�؜5I7�cO���6�6��p���D�����Ok�l�cfD��
�OG�^]��\��mcs�N0`��j `U��G�bJ>�3�^�k `U�T�z���;.B�V���@�"T���n����}XI+�h'\o�cu��(�tm�l��p�\lfG-���F�n�
��
�ℨ'k<�����
��
�[���c���Z6�<�o�� 6��,R^J��؀�
,6\�y��|׫�,�>�;s�6�6�(�z�6���!{Km�l�"$���u&d�x���������9'j�n��mu�6�60/\�P}vԚ�-�7~���@��wF��
ж�G��B�X���b�a��J�UO�x���a0�u2��n@e��Im�l�p�C�쨵u*���{�6��
�����
�1�����6��
���,6��	�<{�xl����O��gt�bӨ��l��u��v~�J�]�����O@����QƄB��!����6�G�������˧b<��Z6��z����S��I��6��p��T,&��n@����������%bsn��tj�����T@����Q;j�J����W�
+������c3]'���x�3�l�9�z�؜�Pk/���#�l���:O����uj�C�;�<m���Ӣ��h�����7�
+�����c��N@��u�Eh@������t�)Q���\s��v�z�T,&��n@c��ˇj��۴�V�:/&�uu�#�;m�z���`�N��}aɨ��� `=�=b3C'���!_�����Zv�,g���n-�E�����&����������i���[v��<\�7��G��з^[N���6��Dm�
�������6��
tP\l�ͫu�RQ_������&�bV�nׂ���mbs�N�@Y+�K��o�{�?�K��='��ݣ=	��"{�cҶ�\���]v�E�u�ւ����P�Q��
XŹ�u���'w	�u��c�eVr��P�3�������?�K������7A\L��~:�b�ټ�c��g�Ö��Ex�c]�n@��56�	`>�F��%��5�Ar�CD��~�������n�󜨏i�k��%`���s��k��;���OZ��{k�+���@�K����Zw�t4\���/D=I7��8=�[i�k��%`�����M:jV���<���W�
+�@�K�����-�Q:#.����;u����΍��5\e/��iM��Nm�H��ˠ��@vIf�e/�q���&-�H�^'+5.�@��s����:Xc���m=Ǹw�5
+�˖�z��ڔWz|�6��_������B���KE})B��Z�:(	�ݶ�c�eՂ��E0?��J��*������ee�p���n��1޲���p��⛥@<9�Y�S�J��Ԇ��i%'`�����\���뼈��`��tG~of�BL��M�-�������_�ZE7�3��k�&`wE��oU�wK���6���ǵ��aJ@��YD��w���������kC[�ǵ�j�Ef���Z �	�5��vB酸���Cu�3����S����A
+�[;�[�k-h9\o�St�!3�T'?�8GZ�|�a"6�q���׍��Q���cf�F���8lYL�.��n�O�`��:��yay�ԁ�E\{m`V/����c�ew$�~�⌨)��Ԍ�E�w��cva'�tˮ�z@�/.^3b��N�5df��6ٺ<{ >�����c�e>
+�X�~al>�@��Y�uQ&�۶N�&���D��7���eЁ�3�H�nN����v�ݱܖh����ҩX��!�)�,��ث�n���|{8�[���1m�|�z�6�
cf��\�-�S�>U�n�<��.��}W/.N{������"��ݶ���l�F-�8n�%Z��p���|Z'�3����&�O� `j���n�7�`��z��|>j5����"�������P�s��'�;�[���?k�"} j;m����E&�ZЖW����dxH;���<��N�}��"�wq�=�в}S�&���5�ݶ\�
�k��4��)�,��6,��Q�ֆ��շ��k�ެ�wZ���,0��p�g>��n�},�,��6,�ZЖ7
+���&�l[�)h��a!;k���sL�+�f�u�6��%Q���a�����\-x���<+6�m�ާ
���M7�H�����f8 j�l�~�YP��S��)�<]�w��o{mX�3��-G-'`�[�A�9V�bє�L��0���g#d?Z+*Ϻ�/mhY���@���Z˱ڲ<�����Pqaykl��	`@�kOՆ��۵�m�S����\��h]{�mxH�����0�����k�a�N���
-�7G��.v?������<$\���U��
���8/n�
4�5mh˻��f(R����pl�%�Hu�6<�iQ��`��>!{)�X�kA[V�z��]/G%3���h-xP\@����u�!�N�+]�E]�
m9$�/>%釀�]�~�ɶ\QE��+�.�`��yrGmX�#��-�ӑ���[&ꌨI�ɶ�Ԃ�����lw��n�,4;�S��C]�ܰj׮Q��{+�0��c�-�H>Қ_�s��6�,R^��mX�ZжcS�'�hr��K��l��Q�І´��Ol��	�qyq�7M0�Hy,���Ж�����#��W��B*ְ�u����6�
���
+)�L̇����6<B~�q�6��Qo��+/罞c�-��z�6�
�y��|�a%���p��S�����~u�6�m83��]�Wk|�c�m���6̕Wj��
�-ɟ*_!�t����?hC[�"#Qk
+؝��d��*�0��0����y�N��e�T|�̃�u�6�-�X�0jY�3���dJ�v���������|�!P���j��3u}^����
\c2`Sv��//彼c�m����1.K��AY�T�8��
����6�-��u��]�<�÷R�F=��I*ƄQ,���6�Tj�͋�h���#���P��D������o�bB{ړǂ훊!"-N�;'�tJ�d��8����AE��
�ȓ]�G�n]�s��(�?��^���$�gS�W1��-��봡L5��]א�M�ݹ���O	�s�8'5p��zy�w����I�˓h�2��6�\t��{��ˣ�p�T"?�h��B��6�tͬ�;i��\u�6T&�m�Z*�b�"?qT*&_�1S�[S�(��ވ8��?������}v���Պ�93��P�<kM��as��։�4��Ie�D�*����n�|K:,���1Q'i�C�=���P��Q?N5�ľ;�a�&j�G��d�_Ն��������c���՘)��Ҩ�iEe�5�G�[��؀��*�uA2�u�N���6̽{�������6�9y%m���G�,BS��?��Q/Ā����U*�0P��Ն��z��|T'�j!��amx�<m_�	df�j���T̢�� �-�.I�x������Q*��_+��5���>�4m$m�
��b��hE����u*� _�v�r��fg��#�L�GM�Պ�w���O�:P+9w���%��!��j!�#��Ǥb�����.�5�J�/T��f��۴�ʜ�x���R��0���7jC�l��%��H�-���.�o�w
�د
��M��_���6��֑�����
�p���qy$E��.�6�����ubj���Y����i#�ѱ��N���
+�����2d�ъ�ɟtϛm�#A����bԛ���o/\?‡�h������

���G�t7h�%`�)w���c*�^���۩�sm��|�����������
#]�<&;/Fs�Vt-h�%�/O�Ðme�V�r~@�T�@4#jU��kF������p��F��Y;�(mX�<���j���T<���;8+Dv4`�o�_�R1��+����jV�˻�GzmԶ���8M�>�mX�����ﵢ��#'G�5�4&4��x�����3BLO����C�0md�'(�:�H9��!{I�X�����S��ݕ�0���M�M���8�j?j_�u������H��-�����X��������X[�b���Q;�b�oz#�d�7��:44tb�B��4eʔy��=�J�y�Gܽ�>�\���%���L�>��+S�V%�3�E��
��-ڤ���G\�j!���l��FGG?�޶�yl�c��6�C�Fݩ
��$�?.�F7���7"`?_�e�T��^C+j�{e���|�0�7
+׵�`<$�
+׋��p
�Wv�<}���0.�E���zxV�)Q���B�\���>Q+-N��
��:�w��s���a\�T��<˘IjD���OG=-S �xy�T�����5�������,c;Gݨ6�<y|�����h��M�>�u*���П�s�v�0!y��<�W�B�t�/j���b��:�';v�Z~�=ύmA���g*f�ˋ�Y�Q�87�b�D�E;&$?�9�
�}/߀z�6��̨'�b�o�pay���VL������H���s�dmh�MQ/N�
�i��ݯ��g*��I;Z�'h��ȋޝ�
m�7���l+B�}徨�M�����<}t�ؼK'�ήq
x�6�%��Γ�)�~�v��I��5#K�ҺÓi����"d/�
m�~*�~GԿ�C�n��S1�Q�Ԏ��Iu�ؼM'�V�p�6T"�~L�F�Xu�~-��CS��� �y����0�fZ�R��:8��_�v�������XU�
+��t�T,��`[=�=�P�_D���d5i�&r���l���:o֒�}8ʸ;������c�5%j��_i���s��JŘ���ʍZR�8������-�����\��R��X
�wZ"`wýe��$j������It�6�0��M�>��6t��X
r�2h_�%v'�1֟L���h�'�]S1�<ܱq�p���M.��OԵZ"`W�֨��ޘ���|��'�Y:�B�!��Ԇ��w�ύ�:+C"`�-O	�ݨ���)[=뼗G=U�X��&O]N�b�TL���d�vU�ռL�ף~��EOVԖ���r��|P'�X�uS�"!��M�R�	�̨u�D��<���?G}���:䜭
������G�
�g×D}/�ǩ�Ty)m��e��s��$�Gz���'N��S�����B���P�<�&?ov]��Q�i���Ky�WD�_*�i?CKZvXԚ����.v[�ͭ��z���Sd���8�F]��v�_��H��0q�'w�[�'q���!�G��AF�Z{N�e����;j%m���.�O@'����AV���A��d��B�I�	�Xr�Z�.���
+�;�Z��y��<t$?4��v<�뢖����.���g��M�ߦb(ȣ�D��7yڛ_�b�u'����v�Y0�k�s��r���:�|'�O}�v���<tf#��8(�+�+��"��?Q;�A��B͊�y��܇W:��H��=�c�WK��ꫢ��p���Q_��J�z��ˢOs�P�A��=)j���S1�z	���Mᅩ'u���b���]@�m,��R1-�驸������%_���2j��y
�����S�<��5�p�qyZ�O�ޓ��u�N��V��v5���b�����Sq3nf2ͭ�̈́�`��T̟��>��^���@��j���~r��<�%?ĸ�]\����Шv��P�O���g?��!�t�Q;����o�b2w��疨�G�su�KzuYGF�����r��a���Q�i�X�ۚ��L�>�n��������P�t9�����V���r�W��7::z���0iʔ)�Ky��G�<�y�O�7�
�X����<G�]	@��3j������󐐣�`��]7�:7���Y����1�wD}�|ה��̫^5Go{j�T��ާ�?��!�tC�
+vdž��|���u-�-�Qό� jƢ�����n�:5깩X�����˧b���R��̞<}4�[؅�t��
|�y��� ��v_��ʗD��������n4�2�H����U~sw�{��Q_,wS<�n��^:y�h������wӀ��\#�r���o(���u�D�H;���[~����4ry��엮���/�zlC^�v�]��Z<�!�5/w����춮�y�k�����7��Ū�;?E�g�X?��o���j����ny�v�]քa"�N���%쮮�<�Q[F�uO_��f�V 9���o�ߺ�_�����4���Q��U�t�Kj>L$�m�!����Y����Kw��J�y����/0���"OB��d��!B�C��բv���ur*nJ�?*Cu�~e��I��J�5�e�>1�>�����U�z���蕗��5�5!�k�◩xnm�T�Gu��CGI���K���+r�9�׭��<}t�T��^��M��G��n鸼���R1��E����������y2�v��p}i*>���ќ7���'O�\���ƨ�vI�͎�$���Q������;˾�|P]��;�P��[vOŰY:篩X��g7t��>���/j���;:�٩����,0@�������q��w_��,��Lv�WR1.����yuԛz��'O�wҟ`7��c;�5�W�'OS{~ԊvCG���B1�H�Mܞ��;���v�:2Yv�S��ڦG���k�� ?���|�<ߙ��U���:)�]�T��(Hŀ�<d�v�J喊:/j�|����0���b�8���T�@�U�^T��}5�YQr�T./�~\��3�������y��,m�cS1�y�n��u���Qό��c�r��zA��������@Mlצ������yƴ崽r�E�=��:��:?���T,ey�c�r�D�Х﵍vP#�Dmߥ�'x��W*)�7����41�H���W8�*��yo����uӍa"kF}P�+��V������&�Ø���3��]����&6�h�.|����L,Я��<
ߗ��b�2�y�y壟;�*�T���1������4��f�R^�:%_�^�͕����)/�I+	�+S�]�:yJ��:���U�j3�5�t����Z\�wG�ڤܴ�:�4/J�j=T��Sy�������k?쬽��l�QM{яj`��I�2�8�*��ߡC_��k�-`�Wk+��������І�U{<�[��	���)��ώz��V�oQ{E�-`wW��q�UbǪ���飫���R���"�U�T�5���J�I�C�75�hr��s!��iߡ�<�z��PSy�-+�z�F�����c����`Ɇ�b����m{Y���R��3<�~uUԥ�oI��-`ը�����-����R��z�vV"?kwd��%�`G�D��R�d������S��>2\��n�3����{�a������>8���
��yQ.If�U]��2�n_��ڨ{���<�OvH��}��m��Z����yԤՌ�5
�������H�_���kNN���>>�ۭ�m�"����~�g�d�'�l��[�L"yv�>������_v��e�։z^�g���'w�8�̘/��y�v�{���V�E>�߽�o7��U�}��~%.�/T{�ʢl׬*D{�V��Q��Q}�cNO�R�B'����تS�ޥb�jGG��ohzt��\��m��]��q��#�]�1b��V�-?�r��]?�E��l[^)s�
+N6t6���1C+*5��u	��DM\�[}�60A�N)�J-l[^P��&�跻������mY:j�6������h�S׾��g�[�};l�L�w����S��m�H���v��t���ݻxv�\*d������'������m��<�g�ړo����~�~�y']�xmˮ��r�U��t�U�C��تg0��}	�h��^�׶��կ��xm��eȞ���GW��ZZ�u�&w:'j�TyMp`2�x�hB+6�kW�+�H�����qY*V�u/l��{�;3��	��)CknI��&hE�Zv������5��ׯ?X?O�v��-��x|������;����+1ΊM��9�YeM��5�Yd�Zys���%�wVq,���~���%�{��y>���؎5������ku��e`���T�ۺ��<�����?��0����}i9t�ie�c�='�bit�a�d�u�����Ǡ
�SQ�������hy��H����
Ӄw�[����<-�N��
+�˱_����9���J�^"jGmkY^���~��}���9�۲���5S�`tI�l^��x�S+R�ԩxͭܽ޹�7�V��/ic�Q�Z9�M���&:D䩩�ٶ]>�]�n�+��s������YI�z���E��X�U'���5[
��A�&z{'-k�9��>j�v�a"�[!S�+9x��l��D��MJ�a���_����Z�M���V�Z�����ȱ�'��ٰw�0eYu�������8`o���yȵ�u�L�sr���6S� `7Q�[���G���N�
+%��
-��wl��+��m�=5Ez��3M��q�H~S1i!�K_��E|�\��gx1oAuZ����ʼn\�&?��5��?�t���+hC#C���ո����l蝧jA�~��|7��d�]8F<��[�v���P���#O8�i	g�-�3[iA�.��4�q�d"�ӂ��1�kb��+`��+�-�xL�XD�ھ�-da��5��%D}O��??pl���Z�S�;GVۛ<�}(jF2�\i�/�n��Ϩc�e�hA���b��n�6�n�Ab�T���Jp=D��Ǩ��-Y'jem�V���Y�:��#/E��f�Іʰm	s��jA��Y�%l��T�h����n��ŀ=%����7���z\��ߍ���㽧j7�ݵ��3��xԀ��k�-�@�.Che.����XG'kr��y��|'{F����}�C�-�
ˢ�.��S���k9��2��=>�;�[��tM��Kjm���]�M5���s�|oF&��Z8`�u��ݿ�s�{�^S���+���x^w���F�W��ܰ��m�������8
�lw��k�ڤ��<���뉽�A�����ʲP��_
5hw��u��%kkA��OՆ	�$���ya;Ox`jm>�:X7cv����8o�:ZP�p���;��jٻ:�.��h�>�6�_��'`��i��5AJ0*\W�g����;�y\��� `�^vm��qޒIeȦ^�ڰ���1�c���د*C�!�w���K�^��;�[�-��Ye���L�6,{{s��:}2��iunt�5P��;�r�[Cja�Cp�Q�����Kj�o(C6�({	صr��ܻ�>��f(lu�����2l�r	�<Lă���wD= `�,�jZP;y�2p��▛�d�bڧ
˰}�|�aV��?�=�����%`��ZEj)��<Pzb^��5_�Uֆ����o���@�K���{�-[QjkDઍ���Ir�>��S:�ρ���A���v�z�V��Ghw�ü�*���ٸ�z�Z�����*����0��\����`�������iӄ̛�b�|�UW%�$7���=��X�R�J\'`�]6�2�!"7iS�᫝�-p5G�������̽9��?������[���ݵ���w��g�2d���N�^Z���NYr��!"�hu耀�L�
U+K��P�ŝ;��"l:���ٹſg�����3�&X{7`��[��!CD���I���w4�˭V+���每���������Mόg�}w����B%�
T`o�y��l��'i6�2������$`W���[����c��56<t�b��9ڄ�M/"��@�µ2;�i]zm�:F��-=:>�C���
�<H��vz���=F���О^�巈T�����M�
��[u��ju~��sw��}�CD���O
�=vN���r�B���æ���JwI��ɾ���W����}�?���G�s�Z90M|n�N�x�No���w��R�>�P~��-���p��D�����*�����&0�:; �7�"����@?�N�����5��v�OO��4-d���b����V��sw��T�ҟt�;��٪e@�Q������0�{�k;��>y��|s5���si����L��M��l��a
+���g$5sf�Y���^������ڸ~lx�O�@����=�#��9��A5�k7����MN��B�i�k�@�n��	�%
+JyX�t��6��蘥Z?�l��7QwiC�.��n�ߔ����O��j�O�y�윌��_i6�06<tl~�=ؖT�x�M�]q�p]K�vq�l��_j6M�ZPI�kuYf!{��2���5R_S�p��;�޿dž���
�؃�Z��0Td�r�K��(~����.i�1ө�����p�1��l����9\[���75����w����9��N:��U�e>55�!�&2<�ƹ6j�6���;���m���q|^���ӳʯ?'Y��鿫�ޔ����o�<��yp�c&M�2e�~止���[rMٿq�<}���l�m����{�Ǽ����<|�>c���
�Ëx�;�<66L�8�=Ɔ��2��w��˴�%W���+������Vr�Ӂ\������l8ߛ(o���:�:�8l��(���;m@�F��j\76<�6 `#`@5A���Ɔ�����5cl�-�@�F���&@�"����
��'�zm@��ɮ���t]�G�i�8��&6�	�jŠ���oh�66������~�
��oEݫ
��؏Ɔ���l/Nf�'w��=�C��+��� `#`��
@��3��ڀ�M?���M���
ݭ
��8�͉��:@���M_2L�*tI���@��7�Jm@���
�36W��]���Y���e���fx66���0>y�[��.�%jT��[c�C���aG��/ŵ�>m@���]��t����A	طi�vS��ڀ�M��+6���v^\s������8S��0�C�c�C?���:@��.�5?�l�YZ�@����������A�f��
�)Y]���"�1?�lՙZ�@�ܽF�f��u�6� `#`CƆ������"WƵ�m@�fН��T��klߋr��v噩fk6olxhN2'6���"�)7j6��s��6|R��46<���\�������
+l��Z�@�N�_���)��&莨Oi6<���н�9V'���O�5�6m@��;=�_���8��>�
ذc�C���'t�q�r\;ƴ�Ĩ�h��p� `�b�
�!"V`q~׌�h6��1Q�j����56����P����:�B�5ӻ��
0�,����TN�
+6�W�8�/��sg�)ڀ�
����<�Yc�C7k6� N�?��:@)<A��=�b0�Ɔ�~�
�І8�~#6�������������a-�x��
�Ѓﻄ�#`ӏF�����u{��*26<tlޡ�똸�C��7=�'֯��R�`��=�A��!`��V��k8,�~�`�|`lx���!`#`wF�`�3�
+��1uڠ_���_+��u�)��mw����
����`�6�Z�_@�h�X���}�Q�]���wk��u�ero�;��ڌ��9�}������"�{wl�;��֥q��ĵ�A�f]^H�x����%�}'ߵ��ڇ�͠X�f��Ш���r����U�}�����bfO����Yv@߸3�]5z=y�U�l&`��u�]�f�
��!��쒶�*`��mX�4{j�16���ƻ:�X�=��1^�=�DM���:&�v@c������j���d��]��Y�=˧~\6{j�+6����:6���5|]O�k�.�nج�/*B�������8���隇��\���m۪Ư퀨�E��r���Н5|]KFmn��]����Xo�����fOM7��Mv@c|*��e5}m[F-k�]���w�w;��2��/.B��؜g7�^�Ꝯw��mg��:Q���5�1�&�
+���<6<T�y����d.�����fO�;���	��.�p}�k��%`����m۱�/0Bv�Q�L�
+�v�]�?/�QԺv��%`����m۹!��ۢ�dw���c�C7��5�j7�\��X�}k��&2���ؼ.j�]P�G}��sO�J��'��j�ф!���|��蹼���q^��M���v���v{�m�wSL�^Q��Z����z*��&���
���.yK��w����ٶ	/4N����~Q�m�=qR��G�Z_mw�[�Ĺ�9�'�8�/6��e�]wU���Z�L�'o	�-�gY��Q+5���'�v@��1�{ϞژU���|T�_	؃���J�p�_S^ly�U�]v@W�>ν74��q��e���m�����t,ʼn���9�n�����ީQk�m����:���Ĩ����fl>a�t�h�;���m�U&����=x�u�W�}
<����]P��zw}O�^s�Q��]'g	���O4����L>)��I/8N���b.�?�}��z]�cנכ�^i�U���`�o�O�����5�H���K����*q|�[/h�k>$�������#���!�mڋ��O���pe*V�mڵ�}v]���`?t�W.�kj`��LlN���ZvK*�]�۰�}Jjا�
p]Կ���=��["�̨e��Mzh�Q��p�����WF�i��Wv���̇�	��.I^�u�s���.��������捓O.;��6kAG�1ͯn`��[��#�D�Oh�k^!��������O3.���tL׶mCv~H�v�b�U�ްל�2��������[l���jCG,������"d:6'ۅ��R����
{�y��쾎�������Z=m������A
��>j��w5�u��9�霋�@���Z�Q����i!{����B���G��q��g�^w^������?�{��Eݮ
��T�
޲a!;?��K�_�B�tg*�\��aY�Q����s�R�~�	�G��f*Ƽ?�a!�w��5�f�`y���qNl�*�y��� �쾮8W���tE��Q�Oœ�M	ٿ(��a*�u}A�^o�%$�x�]�yitC*�G�f���k��̨+��kPȾ�<Q�#4M��zR*�ZM���Ӵ@�^����)��U�E]S�q,��[��'�~�M��zr*f�+4.c�u�-��{Έ�G�j��D��5$d�H���c�}�)s]/��OF�p�]���;3YSD�^�<�Ј6�Ĕ2d�_�
���|������^P�s�yM�/S�l��ֽ�I-��-�I��7����v�C�q������<~y�8��R���K�~�rc���Yخ�{q���Xzj�T�˾!��k��z\|ޛ,���+�p}k
_��Q�J��;�Gmjw��,-��k��BSw`ԯ�w����u�9��v��v�D���f�kըã�gGmaW����1��=������?
+�#�;�X��-�ɶ�B�v�C[�fW
�����9��5zMy��3��5���T+3�@���#������1꜡���z~���L-��4���v�I�Ϋ������70���j��k�%yj�󴡶�⯌�vԟ#d��i���tgl^$d
�ݨ��9����<e�kS���_��M�W�Y^�ڰp��L���~ԯR1�f�.�QF����U=md��2;�Z��,������O������j�{�b�ܼ5�^s�	�D�����wiC#� �a���e��"B����驸#PG�E�0�u��P��2P�zv�vC��`7N��!�B"�xGG�Yi��v'�{7�q\��z]��vPC�Jŝ�n��wN�	Q;
+׍��A��!`/�Qi-�<�T�fYu�..�zQ��H�96ۏ�>�
vU��kgi-���&�;O7��z�=
+�4��Q���G���)���
��ό�K�\Ԁ^9��wi-���Z����6�F��Jl��R�VH��Q��9�r�~��<ߵg���j�1�@!;�7����I7�.���8�=�i-�7�%��;"Y���B���X�wL7��3`=���Z�W���6؝vo�N�����}C��O7��*��q�q���S{o�����^��qm�j���>'+�T储g�9�ZA�BDGh���mߌz�6�f��wlv���n����Ճd�/���Q*>��KjA[N��(��������zݴ���<ji]&(���|r�VЦF� �f�h�;��;,�|m������>�O�L@~&h7�
+����N+�^�+�u�VPAȾ26O���n��g#�6���
+ڔ?yI��B���{�w|�i����\^�fV�"���3��F+� \�1�k��]7���
+�T���Oo�,��:�'/���F<���*
+�_�
+��!�GuT��t[[G�B7�������pt��bi�=µ�ݤ�������Bv~������m$j�8'XM�*�Q��Z�n�;“���B����F����a`p��s��Q�i�)���'�v��E���d�G��������?����ӵ�
+��gD]�v�},�ܢT����������>�M���R+��yQ�F�A+�~��U��U��c�C�{R1$	����������J�Ю�Iz�y&5��v��$/�?�9W+�(d�����S�������� ���ʼ�ϏN�V��T~b7���*f�*�v��������@#�;��zN�N�Q;�H^��)Q��
+{�5%��������Xy"���@�����˿��A�q����� �u*�6Ρ�G6T��O��K�$����'Ny\l�1U�k'luT2���=��N���ω��vPQȞub�q�d�S���GmV��x�vP�|��T<��c��Is�]{J���n6U��E�<0��:��?����G����t�f�ےg�l��/F�X�Z�� }Zl6O�3�7�G����M�wrD;�H��#��o�}W;lx��T�:U��?�;f����E��ۮJł1�D�4��\^�<��]k�q�/긨MS��T�ϊ�fQ_�
��)��U�AE�Bc��znԯ�C�f��5-�Y�T�o�ګ<�,������� 'F�Ɂ*�Yg>�Ĩs�g�lږCж�X���AEA��Q9d�8�U�!*?��d4�0U�A:��q����6����[�s=8�&-���}Q*��; Y��Z�wޜ���(�*y8_~H}���h��M��uJԆQ�
+�T��J����I^�˃X0>O�C��w褨{��
+�O����~�6ݓ�b_�|��|�T���W��\_�,��QG�sp��u��Ц���R�PL�w����6h���;����Q-����Ϩ�	ɓ�>�<L�ܖ�q���Ȭ��h	m����Sqc�Q��%6�z盧��:�9�w��ߥݠ�W��7s�_�#��`�Qe��������Qo�zB�[�I�ʒZЗ�SV^���xxm}m����?��u�H�%�é�A����|����?��6�ay|�'���|:ط���o�᛼�j��)OHf���BA;���w���8���N������w״駩���qQ/��������=�"����T<<��y����0���/
+y��O�;F�-Q��ZAw����fıq��I;hC�=�̋˜	D����;�P֊Q/�zI�]Q{�`��ul�A�]���g��@gh�<*�|�MG;h��R1w����@����e-�}����B{�@��3+A;O���T<����PsyH^���8��� ?��R3�Q��l~����wF��h{V�7�"���p����E��C��,$��5�CЩQg[��S?��~*�]�7f�i6㕗�=��l�������$�n�j�����7DО�����x��G���ܼn��+�¢�c$��(�$�{Qפb&��D��saY��;���L��������.����ͬ�K�x���o֠򊋟�:%��1�`!���E�����a�N�A����X�����I��K�q�}�|�n��Q�I��Ġ�?F��]G"lo����rm�;T,�y��u�e�^~h5�$��|׭y�w�MJV�D�����w�Z�IeȞ���<��*����.����tٲ�L�v2��g���a���X�f8�����,����r������IKj-?�����7�w����r{G�����s[�s�^V��4w��Is�����k�b�^QώZBWX��..C�W#Tߢ%��
��?�ȋ"�;�;E-�+�bZ������}���-��<h�2l�H�Օ����^T��oE��GK�����Rl���!$ۦbϓ������S1��Q�5� `t/p�d�L$�,w���L���?JŢy��+#P߮-��
P�нI���''SC�E�����?,���]���A�;O���2p?����:������N�8�������ٻwԄ�0�ӥ�q�(عݮH�2]���܄��?�#��F}��R��x��Χ���86I�eI�q�F���;6K�
+�_�O����Y��4�P���:�1�y*��}9���8��|�=J�{P��%�b��_*�Q���>~�Rl�k��#�|V�ݍ�k{�S�|��mUE�"Bz�@`�#����N����>���/D���� ��੸��6��l����������
������� ��@`�����6��l����������
����6�� ��@`�����6��l����� ����
����6�� ��@`�����6��l����� ����
����6�� ��@`������
��l����� ����
����6��l��@`������
��l����� ��@`����6��l��@`������
��l����� ���M�������N����IEND�B`�
\ No newline at end of file
diff --git a/web/modules/webform/images/addons/webform_sugarcrm.png b/web/modules/webform/images/addons/webform_sugarcrm.png
new file mode 100644
index 0000000000..48e424b9d3
--- /dev/null
+++ b/web/modules/webform/images/addons/webform_sugarcrm.png
@@ -0,0 +1,85 @@
+�PNG
+
+���
IHDR�����z���
+������	pHYs��.#��.#x�?v���iTXtXML:com.adobe.xmp�����<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c145 79.163499, 2018/08/13-16:40:22        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:illustrator="http://ns.adobe.com/illustrator/1.0/" xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/" xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#" xmlns:xmpG="http://ns.adobe.com/xap/1.0/g/" xmlns:pdf="http://ns.adobe.com/pdf/1.3/" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" dc:format="image/png" xmp:MetadataDate="2019-05-24T15:15:08-04:00" xmp:ModifyDate="2019-05-24T15:15:08-04:00" xmp:CreateDate="2019-05-24T14:57:48-04:00" xmp:CreatorTool="Adobe Illustrator CC 23.0 (Macintosh)" xmpMM:InstanceID="xmp.iid:a6f53d84-f28f-44f9-b654-4f02171286c9" xmpMM:DocumentID="adobe:docid:photoshop:a0671484-693a-1c4b-b30f-3bfc5d663c5e" xmpMM:OriginalDocumentID="uuid:5D20892493BFDB11914A8590D31508C8" xmpMM:RenditionClass="proof:pdf" illustrator:Type="Document" illustrator:StartupProfile="Print" xmpTPg:HasVisibleOverprint="False" xmpTPg:HasVisibleTransparency="False" xmpTPg:NPages="1" pdf:Producer="Adobe PDF library 15.00" photoshop:ColorMode="3" photoshop:ICCProfile="sRGB IEC61966-2.1"> <dc:title> <rdf:Alt> <rdf:li xml:lang="x-default">SugarCRM-Stacked-Full-Color</rdf:li> </rdf:Alt> </dc:title> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:86ff27c9-99d2-40ab-85ad-1d965c14f34c" stRef:documentID="xmp.did:86ff27c9-99d2-40ab-85ad-1d965c14f34c" stRef:originalDocumentID="uuid:5D20892493BFDB11914A8590D31508C8" stRef:renditionClass="proof:pdf"/> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:e420c5b3-5c3c-4752-a492-e8dc2b0f9ad7" stEvt:when="2019-05-24T14:56:23-04:00" stEvt:softwareAgent="Adobe Illustrator CC 23.0 (Macintosh)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:c0322fb2-dba0-4691-83e8-df97960c235a" stEvt:when="2019-05-24T14:57:48-04:00" stEvt:softwareAgent="Adobe Illustrator CC 23.0 (Macintosh)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/pdf to application/vnd.adobe.photoshop"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:86ff27c9-99d2-40ab-85ad-1d965c14f34c" stEvt:when="2019-05-24T15:15:08-04:00" stEvt:softwareAgent="Adobe Photoshop CC 2019 (Macintosh)" stEvt:changed="/"/> <rdf:li stEvt:action="converted" stEvt:parameters="from application/pdf to image/png"/> <rdf:li stEvt:action="derived" stEvt:parameters="converted from application/vnd.adobe.photoshop to image/png"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:a6f53d84-f28f-44f9-b654-4f02171286c9" stEvt:when="2019-05-24T15:15:08-04:00" stEvt:softwareAgent="Adobe Photoshop CC 2019 (Macintosh)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <xmpTPg:MaxPageSize stDim:w="3.000000" stDim:h="1.000000" stDim:unit="Inches"/> <xmpTPg:PlateNames> <rdf:Seq> <rdf:li>Cyan</rdf:li> <rdf:li>Yellow</rdf:li> <rdf:li>PANTONE 7461 C</rdf:li> <rdf:li>PANTONE 370 C</rdf:li> <rdf:li>PANTONE 2955 C</rdf:li> <rdf:li>PANTONE 151 C</rdf:li> <rdf:li>PANTONE 2925 C</rdf:li> <rdf:li>PANTONE 166 C</rdf:li> </rdf:Seq> </xmpTPg:PlateNames> <xmpTPg:SwatchGroups> <rdf:Seq> <rdf:li> <rdf:Description xmpG:groupName="Default Swatch Group" xmpG:groupType="0"> <xmpG:Colorants> <rdf:Seq> <rdf:li xmpG:swatchName="PANTONE 2955 C" xmpG:type="SPOT" xmpG:tint="100.000000" xmpG:mode="LAB" xmpG:L="20.784313" xmpG:A="-8" xmpG:B="-34"/> <rdf:li xmpG:swatchName="PANTONE 2925 C" xmpG:type="SPOT" xmpG:tint="100.000000" xmpG:mode="LAB" xmpG:L="59.607841" xmpG:A="-17" xmpG:B="-45"/> <rdf:li xmpG:swatchName="PANTONE 7461 C" xmpG:type="SPOT" xmpG:tint="100.000000" xmpG:mode="LAB" xmpG:L="47.450981" xmpG:A="-20" xmpG:B="-44"/> <rdf:li xmpG:swatchName="PANTONE 166 C" xmpG:type="SPOT" xmpG:tint="100.000000" xmpG:mode="LAB" xmpG:L="56.078430" xmpG:A="56" xmpG:B="67"/> <rdf:li xmpG:swatchName="PANTONE 151 C" xmpG:type="SPOT" xmpG:tint="100.000000" xmpG:mode="LAB" xmpG:L="69.803925" xmpG:A="47" xmpG:B="79"/> <rdf:li xmpG:swatchName="PANTONE 370 C" xmpG:type="SPOT" xmpG:tint="100.000000" xmpG:mode="LAB" xmpG:L="53.725491" xmpG:A="-27" xmpG:B="50"/> <rdf:li xmpG:swatchName="C=35 M=0 Y=100 K=0 1" xmpG:mode="CMYK" xmpG:type="PROCESS" xmpG:cyan="35.000000" xmpG:magenta="0.000000" xmpG:yellow="100.000000" xmpG:black="0.000000"/> </rdf:Seq> </xmpG:Colorants> </rdf:Description> </rdf:li> </rdf:Seq> </xmpTPg:SwatchGroups> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>+Q����MdIDATx���w��U���ה�-�t�^"%��E	H	H��`G�z��"����˵~)Ҕ*Y@ RDB�bR%@�&R �l����q&$����Ι��}?�}x/;s����ξ��9���f������DQ2�DDDDDFJaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"+t�$��K 1Q8p�c���/�`�@����l��f�.��Dl.DaVD���hp6p�� 7y	��<�`n[%ky��d��\�¬� 1Qpp�A
+[�5��\
+ܖ]0��|��.606�0+"���hgL�=�T�P��+�K��>g�6�B�&��BfE�����`��R��x�����삹�e_D�-�ɀ���Y)���E�afa?�T�!7�`fk����(��Q����>�	�{X����Wg�}3�:D$fb�cs!
+�"R���E	�PL�=�
����n��������[D��Q��J�_4�N�`V��b&�^�]0�ՠ��h�M�ͅ(̊H��1��6l�
+��ɰ�@�;���\��DHl2`l.DaVD
+���h[6�p96�
+\\�]0���k��M�ͅ(̊���'c�p9�pf�M�s��.FD�)606�0+"��=�e�\N��ƴ�z"�RD$lb�cs!
+�"$�/j��u��.'Lì��6�`�Ơ����&��BfEF���E�`��
+�\N�uaZ|y�s�	Nl2`l.DaVd�I�_�
pp.�s��D����+������d��\�¬Ȩ���(�������(��V̦����f�GD* 606�0+k����cKK���Vkmli��R���H�&��BfEb'1Q
p"f3����WN���삹=�#"��&��BfEb#1ў�e�\��:���z2�bDĎ�d��\�¬H�%�/jN���:�#C�1���e�m���d��\�¬H$%�/:`?4\���3[�P�ňH�b�cs!
+�"����hf	��p9R��1���.��6�bD�0�ɀ���Y�PK�_�>�	�'���V$e�,~ܝ]0w �zDd�ɀ���Y�PJ�_4�N�`ۀˑ�y��<�`�+A#"���Q�	���E���YأPK��,,���ޚ]0�7�zD$'606�0+���E�b��Āˑ�Y\x�s�	���.606�0+�1?|�؍�#��t-
�D��斱�y�+sn���*.Pg��Hɚ����<f��Ύg7n|cǾ���Ƞ��k���ǾPW߰'p䛠0+"%������a׺�2����7�����^?0�
��]2�������i��T:=�5�D$>fEĺT*=y��	�;�����{S������˒
+������������@}�5�H�(̊H%���������wmڴ�����L&taR&�T���&[�R�t�tM"o
+�"R�t��e�xZƌ�vuuбic���3�Ēںz��u�
`Z��\���
+�"Ri������d���������]�)�NS��LCcS6�J'P?a	�¬�&�J'�[���2���.:6m���#6�b�(�HPW�@Cc35�oM�*ĊH`fE$jj먩�c` Cg�&:6m��O�E�EUU5
���74�L��.GD�-
+�"*�d�Ʀ�Z����c�F:;7�U���K$���7���Duum�刈JaVDB�����q3v<�ttl�W-�ʮ�����f�H$�A�#"2,�Y	�D"ICc
�M���ҹ����v��˖dҴԪol���:�rDD
+�0+"�RUUM���4�GwW����V����������ں	����Q��HJ$��7�;�����tt�������K��f����TZD$��*&"��J�inGs�8��;�l�Z|�M"�046S[�SeE$>fE$Vjk멭�g` CGG;���Gu��tU
��444����Ē¬��R2���iMMc���ε�� ����D"I}�9ؠ�F-�D$�fE$��kj���e��:;́��=A�e]uu�9ؠ��DR-�DdtP��Q#�L�������5���D�@�d2I}C
��j�%"��¬���M�I����k)HUU5c�N�e�x��:�ش���*XMm
���E�������uA""ї��n�����Ҍ�,�j��\NQ�����h�cS;�L�Z|mn�U��D:]t9�Z\	\��YO]����/
+�"R3~��8p�#�H��vwu�ѱ���@_��D�`�fj�"�R+�
x�-+Λ5z�J��Pl2`l.DaV$�f�f�L�,�l`F��%���fk7���W��M�MK���&R�ȵ�Z\\��Y˃.FD��Q�	��Y��bfk�����'�⫫sSY�l>լ�����:��Yp+f���͊�:�Q"606�0+)3~�l��`�k��e`�����⫪�Ƭ��o"��Z���Zqެ׃.FD
+��Q����Y�>̦�ӀH-���1'���뭖Z
MTUה�²���l�Zt1"22�ɀ���Y�ț�e���l擙Djߠ�)F6���s�ö�����������Ƚn����3�ԯ�?�8o�Ơ����%�Ϭ���#w�p��벦��e���s�	�W5]Z^�D���6����2��Tꭃ
��R��o#G�Z�	m7�c�s�`�?5
�6�̬�l�I���v�/Y�}���:�TV�/z{{���&b�ɘ���o���W/�z`�u��b6{]5��~�����d��\�¬Hd�<)=��+�gp봓�m�ɬ�٦�%�Jz�p\ۍ��&�u�(�n���X4��~u1���d��\�¬H�<)����Y��#g ��	���������$"ׇ54R��[����Ak�'�͔2�[�e��ܯ��"!��Q�	��'��1���R�����L�O�>D��SYQ?��б6�s9��n�ؕ73�g�����1�N��_'��Pl2`l.DaV$TV����n�`B�/K�'��a��sߤ���j����S=�����	m7������"���+o���OW�E�0�ɀ���Y���<)݀��bv�����ES��u�)<׼GPe����f^ۍ��4��Q�a�R�i7�o
+�Q�
�Y��;+�_�>�4]�֞kރ��p���ٔn
+���i�og��8��v��T���&�5-�z���K�.Fd��M�ͅ(̊&�_�p|��$�ֲ�@I{�ʣ'U˽���u��<>n���)�}���ym7p��E�f�>�!(��M����d�)ZS��??�DF��d@� "�K0�L�]�h�B_O;�u�fz��4W��t��U�અ���I��S�}��X_]��e7�w-Ǯ����n`ێ��.gPՍd&�V��$�t�P/)�¬��VU�Č�&�gC��;�S5�tY[��\�g��!���OX����:��p(�dХ,�࠵�s|ۍ�������]һ$��n}
�L�if]����M2MK�h��@�F�:�R����D�_*����ws��Y[�
�M?��駰�nzХ
ijWǷ��q+obb���y��4A�zj�����tY"_
+�"R	ɚfjj�a����u�;�Cf�SR�1��u>�엜��W,��N?��&ͥ/YtiT
�q��E�k��9��TK���j�~ԍ�?�&
�]���
+�"RQ�4�I�0	z7A�:���ِ��L�e�u�����X��]S�q����i��2��yNh���W-��oC�?�DjZ�~<To�a��+"RQz���T7���t���?D��6p��8u�U<ݲ��Oeє��L7��1��;8���9��v߰�l�S�t�	��cMw� )̊H��)��`��:�k=t�����}Ó��I���w�g�1�N?��c��6�^o>�	+n��������J��nԍ������BaVDB���|5M��7�2�ގ��ڢ.��q+���
;�pƩ�iꉼY=�����烫rB�
l�iY�-]u�	��c̲��Q��PJ$�n����1��k=���̎9��������G�pƩ�&;L{�Y��2��zy��p�,�I�s?���6.	9�Y	�t���m��M�
S����>_}����յS�u���6�d^����m&w�⸶�8��f&w�
+�ڡ�4�fa�!<�]��OaVD�#�-�+ӷe�6�ta[L�~��K8{�/����xp���~޻�!�aiٰ�T��Y�TU�Ո�OaVD")U���Wo��г�r�x2;��v1���A��.��V-����FD�4
+�"y�M�k��tA�Z��AW>�Z3[7֬�����Hl$��0�|�u����7�s CI��~T��=��H`fE$��ꡥ���_��/D-�ʭ���ڱj�%"�0+"���_ݹMco��ŗ-ɴYBP7�,)
fEd�H�B�4h�j6�u�3�Ǣ���l�i1��DDF�Y���@p�M���H��jǘ�^]�͌m&|�)U���5δ׊�5��_]��D_"�>6%Jh:B$p�o����8
+��j͞�&�vo 42�M��n�8s�A��w����#��A$�b�cs!
+�"���vz�	�l`�@�)�@��������1'�m���`K���e���W]��l��Q�	�̷�I��\�D R��v�P��fe[|%�fD�x��^K�^`!�[��ԅ���9�Hx�&��BfEB/����c�9���S�����:��8U�[6�`K��0��J]ؿ6�bDdx�ɀ���Y�H�|;}�fm�i@c����:�C�zȔ>^2��L_�t]��U�&�z෩�	�)\l2`l.DaV$�2�N7b�p9E�f���\��M�߿�1�RkL$[j=x����c��Ld�M�ͅD�/���]���=0K���\NQ2�f	B�zf�~��l�����g�:�*��ԅ���)M\2`��ŊHl�[����4��{gz���b��^��V5U
�S�q2����ڞ��_	�J�~<�4��?*��3�jH��T��>��5�*��DD��̊H�ξxj
+ӓ�`�x�=>��}�n�t1���,�7������F��$��X��e]"��o��b��u��,��J�M�ͅ(̊D��O�`?L�w���@/�d�xO��w�+)���D��ũ:���.�܈6�
+��.X�R���b�cs!
+�"�w��Sk0�f]��������f�9$���&K�Z"��T�jiy?�,p/���-�]�*�M��pb�cs!
+�"�u��S����~��v��Ls2=<�(��`In�_��@��.��UO�\D�M�ͅ(̊���Om>�9��)��Ց役���
����"ky2��:M��U��h>fm�u�]�J-�DB$606�0+
+g_<�@�2��aӳ��������5����$kY��cE"�&6�u��ڇ�*BD��M�ͅ(̊�M�؟�~bw��ͪȲo���3��:�t9�l��ũZ����/\���.M�W���+�]��h��Q�	�M����M���?�����i	���L�f88���2]�D��W16l�Rkͻ[j��6j6�cӊ���}'����Gd��Kԡ	"R�����ؖ�=�3����_�H���cBwOx:
�I��c���������nf�0��!2�<���t-O&kcT��I����kw��@U:9h�	�.�>�Y�*�NL�y�Fvޡ1�n}��^�4��5݄e`��G��T�В�ܦ�m"��kM��փ�Z6���V�$0yb-;n׸n������k��Q��rI�W=~��q��t����z������tؐHrG��;���k�_������#�c��jy���
*��>�v����Q�[U���r;6��)̊H�U���;m��N�7�����Wt�W��&�	G��'�x>Y���Y�3[�m�Z|�H�Y���d-�!�#�J&�:���f4�[��@m�u�H�)̊HE�[�?����gV��L���Ɇ�}A����D��Ruܗ�c�@?g�p2��0�E?U��T˓�|�ni�b��z��Z?�N'��T�^tD$�t"���
l�mon�cy['m�v����K˓i�'������2=��b���%�x U�c�z��R��t��S�9��1�o��E�"2*(̊H��4W1f��ܥ�U��y���u������jy8Uˤl��3]���b����$�jy U�ꐶ�?���f40uR-�T�B���N
+�"�T�S�1��M��,o�d��N�{�3[�:��t#�������k`d�Y��d5�Su,M��~
+�5IfL�g��z�'CD�G�L"J��i�ع��wj�׻Y�����i�O��x��1�ޗ���L7
+h�6���T-��x#�-�&M�e��z&oSK�����EaVDB-��)�j�2�����:yee'���|3���tJ7��@/�d��'�Cz�Mc�$x<U��Z�
mK��N�g�zjkù�AD�fE$2jkR�2��]f5�f]��:Y�����pD�,�L��g��4�8`��ٙ����l
+�,l2�`�$3;q|M�刈MaVD"i��&����o�WVu�������i�ՑHrO��{RuA�2��&�Rk��:����ED
+�0+"�VU�d��f�l��
},o���.���1[&�t��SLK��-�A�#"b�¬���ؖ*ƶ�a�][X����]�FxZ|eܘjfN�g��:����Q���I�l;��m���������X�IOoxZ|�[uu�ms-���R/"�W8����4{����4���=,_����zB��˦D¬%�nz=�'ՒTO-fEdTH&̮���j����⫳+<-�F��6���f�N-�Dd�Q��f����_W�b���u�&^_���m���zxZ|"�L0y�Z��^�6"�Rk���)I"����8M$p�K�L��}mp9E����U�,o�}S����1�k�UOMu��7��K�e���f/Yt1"�]l2`l.DaV$4Z��I�G���'�����^��u��j�L𯑩Ԗ�Z��D�G	��x�}�f/=��DB.606�0+J�K�>��^�S��L���v��N��P�_c[���J�#��OL��j��%�.FD�-606�0+z�K����4\NQ6n�g��V�ꢷ�|���UIfL�c����R���͛��Ѡ����&��BfE"�u��Øe����dyuu7/�u�v��_�LW����L�TK2�׳��K����^�t1"R��d��\�¬H$�.��f	�ǁ��S�ή--����o�U[�b�4�R��.r-��Wbfa�	�)^l2`l.DaV$�Z�Ω��ۣ���Rg��zm7��:Y�zü�&	&mcfa'M�%b/]Y`f-l��KtV�H��&��B"�AD�ֺtζ�Y�_�\NQzzxe�i�cK����Rk�i�l��
+p9����;b�cs!
+�"�ӺtN��f��	@U�g����z7���e��ȵ��bfa���Z"���Q���֥s&�g`�!�p9q�f3ו�f/Yt1"R>�ɀ���Y�Q�u霃0�N.':��0��
+����d��\�¬ȨӺtN&О�7�r��Q�2�?̛��=�bD��b�cs!
+�"�Z��9{afk?���0[\���}2�bD$8�ɀ���YZ�Ω>�Y[{j�UFY�>����^�p="�ɀ���Yy�֥s�Ǵ��0=�j��--�^�	��d��\�¬��u�p4f��@:؊ʪ�
���y��4���
+�ɀ���Y)@��9��31�v�˱�y���z-�bD$�b�cs!
+�"R�֥s������u�V4"]���Y���^�t���d��\�¬��P��9��G1�v߀�)��1���̛�dC�ňH4�&��BfEĂ֥s��,A�8�l5o��R��y��<t1"}�ɀ���Y��u�Z�L�=,�R�����0o��������M�ͅ(̊H��.��#&�~�\��\�i�u��K^����(��Q��2k]:'
�Y[{��8|�����y���[[D�]b�cs!
+�"RA�K�L��Ԟ
�*a�1���7{�*���$606�0+"ȵ�:3[{2PS��z��0!�>��� �&��BfE$`�K�>�Y_��An�����y����dm""���Q��i]:g?�\�8r��Λ�dI�U��l��Q�)X\2`2�DDDDDFJaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"KaVDDDD"+t��U���{�݁m�)�$����/���U��e���R|��
+W/Q�����0ϵ�&�9���@'��^�}�
X���Pu�8n3�/��g��wu,P��	`Џ�y�^ڀ������^_���
�y훌y>����6/c~^���3s�0S�n��T`"�5���0���������VT���8n508����o܀�w����Va�~-����1���e�k�$`��s�\�������v><<��6���;�����'b^�j��@�+6�V=Ö�;*_x�$��l�5X�H$�
�;'�G�`�T6<��
܅�uY�x�{�W��\��`���8�{���8����m�S���7���>�;����7�{�<�~��G�x]���Gx_����pp�ͦ���A����,�Y:��i�#|�[3��i�4�l�P U��_��~ZRu�r܉���0�6�8�*�v`!p7��S�x���:}'�wg�c%1�+g�P���p|�/��q���/�{�Y8n#p"p
+�������㛁�*M��\Ñ�V?���{���53����c~�?�y�W��>��7��{����s<�@)n��˭�݁/X'�0k����;fFĆ��c�_ท����>F�s��f7�	.gc���ex���#���O�W`~W7���
+U�s�
+��Ի9���Y%>F�9���0��UG�
+���Z��^
+��[n�1���u�M`�0k^w>�����To�����������|	83�jC[�]���
+�1�����0_�L��[5
���ǽ	������#Ca�|4�E�|`|�	���q�|3���I�v�{�#`�2>J���8�π�ަAn7��5���X�߀0oj*io������[_�lhy�qܱ�o0�\�f~����7�Ù�|�
+��k��p��q�<`?���ԧw
+�������XM����q�jK_�帻��JkxU���i8�����e~����7����/*d�i�F�!wN�u�m�;&��r�
�[���!~:7��N�	����4�z�+�|��Zfv�Y���,q��}6�,�z��Yǝ��ވ��D��Z
+������,g48�1��6�,�퉖w��ښ����p�
�[k�L.�ǝ9�Q���f�q�������?pܹ|�@E��&ǝ�Y�z�M��l���Q�ǹ��e��?�f>3�{qܯ��G#̚�u�����D�kǟq�0�~�����e�3>Di;�����O�� 5�?��q�
���
6۞�q����2�
ǂ�ַ;�x�������#u ��h��q�k�W�\�I��8���5�¬��ٽzX��%�Y�pn��D����;{;��u������dAq�s1���x�=8�B
+dffw;�.�G���U8�/�k�7�WY��q
+����B�;~%�RMqyfm�c@f'a���[�=�S���
x�� �3���:�g0�������y���A#Ep��_���y@Unw�����Y�K��(�܍�~�k
��<�q�:�V��h��.��݅�q~
+���
3�؉	O5����%�{���|�m��p�3�?���r�9�w|J����=�jf4����+�Z̛ާ1��k0ժ0��1o�ga����S�f�O8�~���!oe�������%�6��`6�u�ly�N�l#���=wy��֌�0���,Ž�	�w�'�{�)���:�2�p��b�f��0En������F�$|ﶠ�F3p1&ą��`Z��Q�Ӛ���C�^q��Ͳ�1m�fx�j�7��]S�㕋y��"��&�?��iM��[G3�?ӳwʽ�|����am�;̛��i�|*q�1�2�BMn�q��2����~|������{/\�y�}�y�
q�|_���'���"��#�:��D/�nV܂���=t12���������A0(do#��
+�S\��c�X���8�f�r�.y���ƒ�:��_����^��h��Ȏ	I�
+���'w�5���{��h9�����G�[��	�b� �az��l3�l	���-���y>����|�b��f�OG(�u��;��mL���Rاu���o�@qa��<���ς.�D�E�l\�02���'����ef�$�Av�:����aT� ��Y��
+�������j�{߻8ӗ��
Oi�:wk5�v�u��m~�(�3����{�nfz�:nf�u��[��T߻�Z�J��;�7�s)��b���̈%������\k3��7��݄���'��a��,"+�aք���.Ò	��[m⑰0�'n �߇��nu[fb��Hq�Fa����{�+��ྗ���Ƅ�%�c,�ӳ꼷��3#8����{׆���3�җ�1!��`��k1ljrzV3�j�S)�;���4p��t	U��z���%&�z��U�ì��-W��n�:��1'�<�9
��SR�q(a��xt�o��|)���V)�Y/\	��P���9��lp@��%�^�5��n����4�&L���l����\�1וW�9yn�͞����a��$f�a!3���-�ci�f��g����_U�0$��%��n9���E�M|ìY�d�Qq��瓘�҄�����������v��#�sR��o���0�����Ca/ �l����`8n�[�����t`��K�{M�^��=���v�L����r�Z�:�|ρ�a�޿�^��L<����q�]�\�;���6k�C��+\O1�0�K�C|��]��{�PX�kĜF�_�Vu��{�T]�~�U��rRiq����Ǻ���B�[��q��}���=s����1�#��ni<�-;X����Ĭ����sU�~�	�.����b�����L�[��l���V���F����6�
\�����uhn3��Ƌ��b���i��0�U��w�^�Øޡ�5Я�<�N�DY9�-;���[Z�:Fj� ��w�ɠ��[p����0t�1o�*�|��ln����5�C����{�B��]<gfw6vE�����}�� ;��������	a�p
+�9^s!f��l|��M���V���{��%�w2&�}
+3+nfF�kyoW�>��������^'�w	fݞ�]��ha���PH3�3f�׍Yםo��8n�G.�����G�OV�c��}�y`8;0��c{��6���C�.���f���R����<����{��-y,c1{"F��������N��)�޾ׅ�������vI�s*�������GE��w��1���P�)���Q��M��1M����)>Ӟ�똏4��i4����~��
+|��m�yC�oI����}|����:���{=�Va&�n��)�F����4r8a8a͚�.38����{��d-���ǝE�'��X̙����30�Y��`�����3f�_�G�����N���0�a>R>
�J=N��q�-��U!�<p[�g��A�Ny{
�BY�(�e����0�9
���Ֆa�y��7�E�7�|�t9pZ����i�����b�4����0n,Z�ffM�=Je1�w��r�
̋N����J0l�!��Q�H�v�݃1�l�avfa���{wY��|�3i�a��)�0�Z�����G��e�]��]�����2����UfcV�}!�Y͑{�i3,��޳`>���2�2R7��~Ӆ#�fK����1g^l.�0�D�9���fÕ
/c��cG���B�����?���E9;���{,���,�Q.}�V��hY�H���n�[���Ռ�]���st%
+�ʟ�+��6}3T=pM�b>��qEZ��/�f�rQ)q�6Z��oa��,ĴN)U�����K�d�S������`�fl����?7��T{�a|�����.	`�͉��h��I������+߱�GV����U�l[���6~���!\�ʛ-ŬCN���
+�l�l%Yޣ�̋�"#Ͳ0��صTC�1������g��,d�k%̰0�bc�sf�����j�)����L^�7V����|�k2f�{%�3��U?�{�P�,�v��6�����L�[�x-�8��ƒG��/���nc,�!�pܽ���k��
!�B� U�Xc��ly���F�T�)�7�=o���͘~�ù߫�im#c��s�J�G��B�S�F�B��P�*J�|��+̆Xi�y��Fˠ|l��)=�K���!.ԏ*~�d����k��%~���5�g-�a#���w��>�0���ɷq%,�u��T�
k,�M!=j�q��d����\V�����TQql��ea��(�����%�՝�Qv��1������Y3^	�Z����|��G����|�
+۸�`�~ߕ��z�+$t�յA0$�ۈ��3|Nz�{�B�Ě<�o�H�0k����q��ʺ���z�޲�/�9n
+8��H�,��Ƭ��u�6�̝H���^܇N�R����ĬW�5�aW�=#���oF�p@�p��|?,�M%�c����} p>�3cI|쉝_���FH���qǑ�˃�(Œ�~M���Cʧ���싕*d���^�q�Oa��:~���{�k�&��=-��Kq�E�b�n�0�{{]��U�OO�|d���
`��՟-��~��ގ�Ʀ���������	�|o�'*P���L�¬q�ű������5ǖh�q�\���E�&ߛ��>�UD�e��˰w�@j���n�}?D�i'c�}�C|8n�
0��.��
+_+����F���|�F4��f}/��^DyN������q������R �dcw�Rc�f���||�`f�vļ���
+�2y�|'��\�"D$~�f�k0��2>F5���@7��c������am-�p�j�_)��K���)l�bz��ϖW	��y���"U�H��7��^�=s�M�!�P������@�]�i~7�W��F��Y�6���������}ml1R4ӣ9_���o/"��0�{��'���b9�0:�W�v�.�z�[���$#c�
��ӤF���8��D��p�|���*�a����qOn$�5tM�)��^�v�
+���z3Z��b�7/�rܝ��1!V�����{���DV\[s���G�Y�1�z/�p܋p�	�$C��.s��1��q�pܯc6�)Ȏ.:�YDFdt�Y�߻x/f
m�l|x��	��M�ɻ�X���b��31'@�vf�%<
+y3�-{"K�'��޿����&�i5�_��q?��4!�Poa�$���<��N �7'"R6�+��^�w!�7埂.gc�K�Gq���E�rq�C0�>􉄈�m���|�9|�X�L���#�}�%8��A"��ɏ>���ݣ9�R��6]���W����{�฻���$?�J�~�����~t1�X��1���5��R� ��'�t���Mxo���=8���2A "�?����s��q��く`N
+�?�`.�q�����.d��0F��1��`{�cn�nn����A�q��P�֩�ƺt�f�������q��H�8Lk/�@��{8�K����1�aa�BǏ�{$�Q�#�|�߳��C�*dWX&D$bf��{0�-܈�&���o�5-��.�q����c�f6΍�ha��3�K[m����;��Z���i�0�>���*GD�Ea�P����}]��n�8$��{P�#7�_bf��R|���Hi�;��*'����0Np�w�����^&���?�����l��k�O�{{af�>\GyO�9
+�=�����^+��3p\�ۄO[#�S����y��O.DdDfm�u�������a�e��h�aLފ��v�QHd�u�6����w��q�rV�����BDbGa�\|�߻�;�	���G��}d'�=ma�9ƈ�#(}yӋ���E��<��o�Dd�f+��V�{_Ĝ:���Q����ƒ�����1��Hc\���'V���<��YGx��H(�V��=��,v��-�6v~�{�[���6�\��ma��,�!��/���;V����J33J��[�=%��F�m�0F�<I��o���a���ڵ�����^�R�TZ�0�塈HQ�Ӛ���z��6J���:q����8R)�'�h,?��7pܥ��&���i��hqܱ��KT�����6���,������HDb">a/��_�g��݆黸M	c4厸ɹ��%<�fA��)=̞��^��E�٘�����>̾�M��z����|k�[<��}�R刌fqZfP��g���-�4Ҁ���c���q=`a�i��ƉaVG�F�=y�?��t���fn����+Mdt�S�-u�~V�(���#�㞯�c!�ka�bT�
���L�o��.���m�
���� :�����>��_���sr�!�f�|��DĒ8��e%�_7��)�t���0�#�;��8����_��c
��6��,���y���~�w��&`���8����Ϫ�c������\��q�*QN�����g+R���*�>V����h+��C2�^��k����L����=�zK�,�qw�4�����y���ia�*�����6��{j�Uy�?���Κc��u^�[%J�x���,��%���8�9n���м0�{�ޫ�%>>��q�Z��q��98,�i�n�q�-�54���f h�#٬�N��0�����ѹ&����s�/�^#�j.�8��;(}�ED
+�0��X�S���PK!����x�ή���5|��8�s�s	�ѥ�����h���P�9�^��P���cz,�la���0λ�7���,����y�o����
+T3R����;uJ�H��'��^7p������fa����Lmq���1�
�-� Kc���q��������P��x��8n����=�+0�긥�5[u�;��X���
+<�� k��5~L��[���8?\��c�����(ED���Y��G�W��Y?kv�_�8����5��W|������s���oX�|���-��KrKJ��8��;�1%�gW��L��܇��\�H�[��~�IE9�)Ea3Se�j�Q�|���'��k���ED�[����0��JU\�����l��Ǭ��1��$��\�c<��~�`f���q�í%��qܣp�V�ƉJ�����7;��㸗ḻ}o�m�q���Y����۱�3��y���`�)w�K��T���Me7�O����n�M�
�{�7 �LKD*+N'�m�u�HKc}8	��>���2Ϭ�;3�8�Rm�[����q���Qi����r��<�サ
���x'`w�0���[Aa|o)�{v�7%r㝅�>��><��}ӌ�`f߃����a?T���p�E�Q�Fl��
+�{)fF쟃��g6m�����w�Q�Lj�[�[J�?��*\���ﭨPe�s������j���#"[�_����p�_��~�&?ĴQ��c��Q����2�yv��!<���ٙU�Ֆ������`~����q{�M����W\|
s�ϸ2�}H����sLbf£�6����m,�}m�q_�|�ЉYj1&w� ֯��?>��G�N��q��l}�T�����)���+"�0k\��0�☵��P�[Deq��103��ւ	�c)�G�_�����d��}��V�\M�+~|�u�|콹N<~��׊���S�Gh�.��#1=�B���r�|��Taw�^�h|oee��1�g�E�O��./A"�Na\SW:�:�߀�2>J3c�'�c�����)���.LL��ky������	����
+v���ݮq�{O�_.��{�q-oA[1A{1���:�L|o�<�EB%�a�����V�����{&��2�OO]Dd��bL{��`z�ƈ:߻���[N���~��?Sǝ��^��)�����{me�GD��0�{W`6��A;�\K�r�<`g��hd�������׀G�.�Bv��8����%1Kɖḟ�ڋ�q'����Z�>��R���I��,��}����(�F`^��Xy������6�/`�N���Υ������Q���
�'a��Z�����X#�L;�(�0���/�U8��p�Gآ��=ǽ�\�*��B|߻�������|�8�J�R�p�gq^N��l=;<����^�3e��-�쀿�!�Z��{O�s1k���j�3���.�m|�U�p���l�jL7��Q�Ƀ��>�|��=�	�����s_�8�b�Q��a�i[�`6a:[Lv����(�}Zp�wU���2����f��{���g�.��[� ����?$a�p0��"0�^���{>&��t)9��_]Ƞ�ij�a>�
�a�sO�0�,�1:�^'���H��6a�#�2愱?�cNw{�ڊi�y�`����+Ȋ���	�@��>�ŘE�a�|	󂹺���{�	e�����8h�������4���W�p�wY�u�Z��9h��sr5�9Z�TSrM���ׇ�}�(�Z�s0�{0�BDd��f����bڼ�t9������AO1����{�a6d�R�9�s�%on����mx��:f
��s���C@�����̪}�`6#n�,�8)��o���F�#�]|�Z�k�€+Y���}(��DdH�/�n�{��{��7��p�?��o�޲�k���<`�Gu����J�+����!����f��0?�[*���g�{G�{��:��
���~�9��v?�d��c�s�|�s΄��-<�8���-����N�,��+��b�\���\�����
`�1�O�q���|��c��9��߆�G�	���G`��L������<�����?��:����������+���n�9����N�q�|�����g��߿�喅���uХ����nS��{����6~���\�Ƭ��6�eADBLav33�up�;888s<�
o`N��+pWn
o4�޽�f�`��)�����F�5����s����+�_%<�#%ܷt���)8��t�X�&������2��4�qnj�1�f�MU����3q�/a�s�b:��+I&���>����Ä�R�2S^������wp�;��m.f�F���<�
��{��*m���0��{A{����B^��SL�����"U�����	�l6��%�d�a8n
+�	����LL�q�X޾�3۳�^�̖=�9jy��;t�&�L�>�vY�S�*̮b0�X�9��%L�X?4�)�fN2:�aW���&����&̬�
+`�9�`��m���=����;��F&ǭ��>��9.v&�w�������|{�����4I�8�ly���zԄy����s�������n��(��*�ɀ���r�Y��0g����Qn���Y�FDD�8z7���>�Y�ec���X�0+2z8�x��"""�(̊�����)TQ:AODDF�Y��a�<�R�
BDD�fE��q�q[�.c+��0ƳE����Y�w��#�[t9�z>ja$5���Q�����h�p���az���zc���X�0+b�o0��7;�3�%�{.攤R�!��݈��(�0+b��~��?�?xǵ�絘z����h7�{Kc���X��Dlp�C�{��0�������;�i�嘣<m��{��X""�ɀ���Y	��NŜ�>��{��2������|���-�'""!��Q�� ��]��������-�PG���[��%��E��{��""�ɀ���Y	�����p}l����
+|�$�0����)%�1�K�=�㊈H�b�cs!
+�Ri��	̺T��OO/�r_`��Nf���͖k��=�ue|	Hl2`l.DaV*�q�+���*����n�)��d@��	s�돂.���� +""Q�0+2rW]D����Bh��H)7�	��]�%�G�{�A"""����Y�R�S�>�4�JlhŬ�U����̬�-���/�榰_����Z��#606�0+a฻�W�]J�:���{W]���TV\2�����{�aN�,�F����W`oY�2�̊���.���-�m���{�x���&��Bf%���>L������˴�KDDb�cs!
+�v�������+�}�������
+<���D@l2`l.DaV��q[���P{����_�n���[[DDb"606�0+Q�3�}��������6@�V�����n`5���^���V�n���d��\������>j�%""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""��0+""""���_e�b^䳲����IEND�B`�
\ No newline at end of file
diff --git a/web/modules/webform/images/addons/webform_sugarcrm.svg b/web/modules/webform/images/addons/webform_sugarcrm.svg
deleted file mode 100644
index e9f368c87a..0000000000
--- a/web/modules/webform/images/addons/webform_sugarcrm.svg
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-<svg version="1.1" id="layer" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
-	 viewBox="0 0 652 652" style="enable-background:new 0 0 652 652;" xml:space="preserve">
-<style type="text/css">
-	.st0{fill:#E10213;}
-	.st1{fill:#383231;}
-	.st2{fill:#B4B4B5;}
-</style>
-<path class="st0" d="M61.1,315.3c-1.4,0.6-3.8,0.6-5.2,0l-25.8-10.2c-1.4-0.6-1.4-1.5,0-2.1l25.8-10.2c1.4-0.6,3.8-0.6,5.2,0
-	l25.8,10.2c1.4,0.6,1.4,1.5,0,2.1L61.1,315.3z"/>
-<path class="st1" d="M57,357.2c0,1.5-1.2,2.3-2.6,1.8l-25.8-10.2c-1.4-0.6-2.6-2.3-2.6-3.8v-35.8c0-1.5,1.2-2.3,2.6-1.8l25.8,10.2
-	c1.4,0.6,2.6,2.3,2.6,3.8V357.2z"/>
-<path class="st2" d="M59.9,357.2c0,1.5,1.2,2.3,2.6,1.8l25.8-10.2c1.4-0.6,2.6-2.3,2.6-3.8v-35.8c0-1.5-1.2-2.3-2.6-1.8l-25.8,10.2
-	c-1.4,0.6-2.6,2.3-2.6,3.8V357.2z"/>
-<path class="st1" d="M400.7,326.3c-0.7,0.9-2,1.3-3.9,1.3h-21.9v-11.1h21.9c1.7,0,3,0.4,3.8,1.2c0.8,0.8,1.2,2.1,1.2,3.9
-	C401.8,323.9,401.4,325.4,400.7,326.3 M408.3,332.6c2.7-0.6,4.6-1.9,5.8-3.8c1.2-1.9,1.7-4.8,1.7-8.7c0-5.6-1.3-9.5-3.9-11.6
-	c-2.6-2.1-7.5-3.2-14.6-3.2H361v45.2h13.8v-11.5h20.5c2.5,0,4.1,0.4,5,1c0.8,0.7,1.3,1.9,1.3,3.7v6.8h13.8v-9.2
-	c0-2.3-0.6-4.2-1.8-5.6C412.5,334.2,410.7,333.2,408.3,332.6 M317.5,332l8.6-16l8.8,16H317.5z M317.5,305.2l-24.7,45.2h15.1l4.4-7.5
-	h27.5l4.4,7.5h15.2l-24.2-45.2H317.5z M293.2,324.4h-30.6v9.2h16.2v0.1c0.1,0.6,0.1,1,0.1,1.2c0,1.8-0.8,3-2.2,3.7
-	c-1.5,0.7-4.2,1.1-8.2,1.1h-8c-4.4,0-7.4-0.6-8.9-1.8c-1.5-1.2-2.2-3.5-2.2-6.7v-6.3c0-3.6,0.7-6,2-7.1c1.3-1.1,4.3-1.7,9.1-1.7h8
-	c4.4,0,7.2,0.4,8.5,1.1c1.3,0.8,1.9,2.2,1.9,4.2v0.1h13.9c0-0.3,0-0.6,0.1-1v-1.6c0-2.8-0.3-5.1-1-6.9c-0.7-1.8-1.7-3.3-3.1-4.4
-	c-1.4-1.1-3.2-1.8-5.6-2.2c-2.4-0.4-6-0.7-11-0.7h-15.4c-8.1,0-13.6,1.3-16.7,3.8c-3.1,2.5-4.6,7.1-4.6,13.5v12.4
-	c0,3.2,0.4,5.8,1.2,7.9c0.8,2.1,2.2,3.9,4,5.3c1.6,1.2,3.5,2.1,5.7,2.6c2.2,0.5,5.7,0.8,10.4,0.8H272c7.8,0,13.3-0.9,16.5-2.7
-	c3.1-1.8,4.7-4.8,4.7-9.1V324.4z M216.3,332c0,2.9-0.7,4.9-2,6c-1.3,1.1-3.9,1.7-7.8,1.7h-7.8c-4.7,0-7.7-0.5-9.1-1.6
-	c-1.4-1-2.1-3.1-2.1-6.1v-26.8h-13.8v31.1c0,5.5,1.5,9.4,4.7,11.5c3.1,2.1,8.8,3.2,17.1,3.2H211c7.1,0,12-1.1,14.9-3.3
-	c2.8-2.2,4.3-6,4.3-11.3v-31.1h-13.8V332z M155,322.5l-22.7-0.4c-2.1-0.2-3.5-0.5-4.3-1.1c-0.8-0.6-1.2-1.5-1.2-2.8s0.4-2.2,1.3-2.8
-	c0.8-0.5,2.6-0.8,5.2-0.8h15.9c1.5,0,2.6,0.4,3.4,1.1c0.8,0.7,1.1,1.8,1.1,3.3v0.2h13.3c0.1-0.7,0.1-1.3,0.1-1.6c0-0.3,0-0.6,0-0.9
-	c0-4.3-1.1-7.3-3.4-9.2c-2.3-1.9-6.1-2.8-11.3-2.8h-21c-4.8,0-8.3,0.3-10.4,0.8c-2.1,0.5-3.9,1.4-5.2,2.7c-1.1,1.1-1.9,2.5-2.4,4.2
-	c-0.5,1.7-0.7,3.8-0.7,6.4c0,5,1,8.5,2.9,10.4c1.9,1.9,5.6,2.9,11,3.1l21.7,0.5c2.8,0.2,4.6,0.6,5.4,1.2c0.8,0.6,1.3,1.6,1.3,2.9
-	c0,1.3-0.4,2.3-1.1,2.9c-0.7,0.6-1.9,0.9-3.6,0.9h-17.3c-2.7,0-4.4-0.3-5.3-0.9c-0.8-0.6-1.3-1.8-1.3-3.5v-0.8l-13.6,0
-	c-0.1,0.9-0.1,1.7-0.1,2.3c0,0.6,0,1,0,1.3c0,4.6,1.3,7.8,3.8,9.5c2.6,1.7,7.6,2.6,15.2,2.6H150c3.9,0,7-0.2,9-0.5
-	c2.1-0.3,3.7-0.9,4.9-1.7c1.8-1.2,3.2-2.7,3.9-4.4c0.8-1.7,1.2-4.1,1.2-7.3c0-5.3-1-9-3.2-11.2C163.8,323.8,160.1,322.6,155,322.5"
-	/>
-<path class="st2" d="M623,349.9c-1.4,0-2.5-1.2-2.5-2.6c0-1.4,1.1-2.6,2.5-2.6h0c1.4,0,2.5,1.2,2.5,2.6
-	C625.5,348.8,624.4,350,623,349.9 M623,344.2L623,344.2c-1.7,0-3.1,1.4-3.1,3.1c0,1.8,1.4,3.1,3.1,3.1c1.7,0,3.1-1.4,3.1-3.1
-	C626,345.6,624.7,344.2,623,344.2 M622.8,347.2h-0.4V346c0.1,0,0.2,0,0.4,0c0.6,0,0.8,0.3,0.8,0.6
-	C623.6,347,623.2,347.2,622.8,347.2 M623.5,347.4L623.5,347.4c0.4-0.1,0.7-0.4,0.7-0.9c0-0.3-0.1-0.6-0.3-0.7
-	c-0.2-0.2-0.6-0.3-1.1-0.3c-0.4,0-0.7,0-1,0.1v3.5h0.6v-1.5h0.4c0.4,0,0.7,0.2,0.7,0.6c0.1,0.5,0.2,0.8,0.2,0.9h0.6
-	c-0.1-0.1-0.1-0.3-0.2-0.9C624.1,347.8,623.8,347.5,623.5,347.4 M581,333.5l-16.1-28.2h-20.4v45.2H558v-32.2l18.5,32.2h9l18.7-32.2
-	v32.2h13.4v-45.2h-20.1L581,333.5z M479.1,332.9h-14v0.5c0,2.4-0.7,4-2.1,4.9c-1.4,0.9-4.2,1.3-8.6,1.3h-8c-4.4,0-7.4-0.6-8.9-1.8
-	c-1.5-1.2-2.2-3.4-2.2-6.7v-6.2c0-3.6,0.7-6,2-7.2c1.4-1.1,4.4-1.7,9.1-1.7h11c2.5,0,4.4,0.4,5.5,1.2c1.2,0.8,1.7,2.1,1.7,3.9v0.5
-	h13.9c0-0.3,0.1-0.6,0.1-1V319c0-2.8-0.3-5.1-1-7c-0.7-1.9-1.7-3.3-3.2-4.4c-1.4-1.1-3.2-1.8-5.5-2.3c-2.4-0.4-6-0.7-11-0.7h-15.4
-	c-8.1,0-13.7,1.3-16.7,3.9c-3.1,2.6-4.6,7.1-4.6,13.6v12.2c0,3.2,0.4,5.9,1.2,8c0.8,2.1,2.1,3.9,4,5.3c1.6,1.2,3.5,2.1,5.7,2.6
-	c2.2,0.5,5.7,0.8,10.4,0.8H458c4.7,0,8.3-0.2,10.8-0.7c2.5-0.5,4.4-1.2,5.9-2.3c1.5-1.1,2.7-2.6,3.4-4.5c0.7-1.9,1.1-4.3,1.1-7.2
-	c0-0.7,0-1.6-0.1-3C479.1,333.1,479.1,333,479.1,332.9 M523.5,326.3c-0.7,0.9-2,1.3-3.9,1.3h-21.9v-11.1h21.9c1.7,0,3,0.4,3.8,1.2
-	c0.8,0.8,1.2,2.1,1.2,3.9C524.7,323.9,524.3,325.4,523.5,326.3 M537,328.8c1.1-1.9,1.7-4.8,1.7-8.7c0-5.6-1.3-9.5-3.9-11.6
-	c-2.6-2.1-7.5-3.2-14.6-3.2H484v45.2h13.8v-11.5h20.5c2.5,0,4.1,0.4,5,1c0.8,0.7,1.2,1.9,1.2,3.7v6.8h13.9v-9.2
-	c0-2.3-0.6-4.2-1.8-5.6c-1.2-1.4-3-2.4-5.4-3C533.9,332,535.9,330.7,537,328.8"/>
-</svg>
diff --git a/web/modules/webform/includes/webform.install.requirements.inc b/web/modules/webform/includes/webform.install.requirements.inc
index f5b87eb65e..f6d9a04211 100644
--- a/web/modules/webform/includes/webform.install.requirements.inc
+++ b/web/modules/webform/includes/webform.install.requirements.inc
@@ -28,7 +28,7 @@ function webform_requirements($phase) {
   $experimental = [];
   $enabled_modules = \Drupal::moduleHandler()->getModuleList();
   foreach ($enabled_modules as $module => $data) {
-    $info = system_get_info('module', $module);
+    $info = \Drupal::service('extension.list.module')->getExtensionInfo($module);
     if (isset($info['package']) && $info['package'] === 'Webform' && !empty($info['experimental'])) {
       $experimental[$module] = str_replace(' [EXPERIMENTAL]', '', $info['name']);
     }
diff --git a/web/modules/webform/includes/webform.install.update.inc b/web/modules/webform/includes/webform.install.update.inc
index 2e20cd143e..7b8173fd6c 100644
--- a/web/modules/webform/includes/webform.install.update.inc
+++ b/web/modules/webform/includes/webform.install.update.inc
@@ -15,8 +15,10 @@
 use Drupal\Core\Render\Element;
 use Drupal\Core\Url;
 use Drupal\views\Entity\View;
+use Drupal\webform\Element\WebformSignature as WebformSignatureElement;
 use Drupal\webform\Entity\Webform;
 use Drupal\webform\Entity\WebformOptions;
+use Drupal\webform\Entity\WebformSubmission;
 use Drupal\webform\Plugin\WebformHandler\EmailWebformHandler;
 use Drupal\webform\WebformInterface;
 use Drupal\webform\Plugin\WebformHandler\RemotePostWebformHandler;
@@ -3533,3 +3535,193 @@ function webform_update_8189() {
   _webform_update_admin_settings();
   _webform_update_webform_settings();
 }
+
+/**
+ * Issue #3121814: Webform submission check taking a long time.
+ */
+function webform_update_8191() {
+  // Copied from: history_update_8101()
+  // @see https://www.drupal.org/docs/8/api/update-api/updating-database-schema-andor-data-in-drupal-8
+  $spec = [
+    'description' => 'The base table for webform_submission entities.',
+    'fields' => [
+      'sid' => [
+        'type' => 'serial',
+        'unsigned' => FALSE,
+        'size' => 'normal',
+        'not null' => TRUE,
+      ],
+      'webform_id' => [
+        'description' => 'The ID of the target entity.',
+        'type' => 'varchar_ascii',
+        'length' => 32,
+        'not null' => TRUE,
+      ],
+      'uuid' => [
+        'type' => 'varchar_ascii',
+        'length' => 128,
+        'binary' => FALSE,
+        'not null' => TRUE,
+      ],
+      'langcode' => [
+        'type' => 'varchar_ascii',
+        'length' => 12,
+        'not null' => TRUE,
+      ],
+      'serial' => [
+        'type' => 'int',
+        'unsigned' => FALSE,
+        'size' => 'normal',
+        'not null' => FALSE,
+      ],
+      'token' => [
+        'type' => 'varchar',
+        'length' => 255,
+        'binary' => FALSE,
+        'not null' => FALSE,
+      ],
+      'uri' => [
+        'type' => 'varchar',
+        'length' => 2000,
+        'binary' => FALSE,
+        'not null' => FALSE,
+      ],
+      'created' => [
+        'type' => 'int',
+        'not null' => FALSE,
+      ],
+      'completed' => [
+        'type' => 'int',
+        'not null' => FALSE,
+      ],
+      'changed' => [
+        'type' => 'int',
+        'not null' => FALSE,
+      ],
+      'in_draft' => [
+        'type' => 'int',
+        'size' => 'tiny',
+        'not null' => FALSE,
+      ],
+      'current_page' => [
+        'type' => 'varchar',
+        'length' => 128,
+        'binary' => FALSE,
+        'not null' => FALSE,
+      ],
+      'remote_addr' => [
+        'type' => 'varchar',
+        'length' => 128,
+        'binary' => FALSE,
+        'not null' => FALSE,
+      ],
+      'uid' => [
+        'description' => 'The ID of the target entity.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => FALSE,
+      ],
+      'entity_type' => [
+        'type' => 'varchar_ascii',
+        'length' => 32,
+        'binary' => FALSE,
+        'not null' => FALSE,
+      ],
+      'entity_id' => [
+        'type' => 'varchar',
+        'length' => 255,
+        'binary' => FALSE,
+        'not null' => FALSE,
+      ],
+      'locked' => [
+        'type' => 'int',
+        'size' => 'tiny',
+        'not null' => FALSE,
+      ],
+      'sticky' => [
+        'type' => 'int',
+        'size' => 'tiny',
+        'not null' => FALSE,
+      ],
+      'notes' => [
+        'type' => 'text',
+        'size' => 'big',
+        'not null' => FALSE,
+      ],
+    ],
+    'unique keys' => [
+      'webform_submission_field__uuid__value' => ['uuid'],
+    ],
+    'primary key' => ['sid'],
+    'indexes' => [
+      'webform_submission_field__webform_id__target_id' => ['webform_id'],
+      'webform_submission_field__uid__target_id' => ['uid'],
+      'webform_submission_field__token' => ['token'],
+    ],
+    'foreign keys' => [],
+  ];
+  Database::getConnection()
+    ->schema()
+    ->addIndex('webform_submission', 'webform_submission__token', ['token'], $spec);
+}
+
+/**
++ * Unsafe HMAC construction.
++ */
+function webform_update_8192() {
+  $invalid_signatures = [];
+  $files = file_scan_directory('public://webform/','/signature-/');
+  foreach ($files as $file) {
+    $value = file_get_contents($file->uri);
+    $value = 'data:image/png;base64,' . base64_encode($value);
+    if (WebformSignatureElement::isSignatureValid($value)) {
+      continue;
+    }
+
+    // Get invalid signature's submission id.
+    if (preg_match('#public://webform/[a-z0-9_]+/signature/(\d+)/#', $file->uri, $match)) {
+      $invalid_signatures[] = $match[1];
+    }
+
+    // Delete invalid invalid signature file.
+    file_unmanaged_delete($file->uri);
+  }
+
+  // Exit if all signatures are valid.
+  if (!$invalid_signatures) {
+    return NULL;
+  }
+
+  // Load invalid signature's submissions.
+  $webform_submissions = WebformSubmission::loadMultiple($invalid_signatures);
+  if (!$webform_submissions) {
+    return NULL;
+  }
+
+  // Return plain text or HTML notice.
+  if (PHP_SAPI === 'cli') {
+    $text = t('Invalid signature file detected and deleted. (@see @url)', ['@url' => 'https://www.drupal.org/security/psa']) . PHP_EOL;
+    foreach ($webform_submissions as $webform_submission) {
+      $text .= '- ' . $webform_submission->label() . ' (' .  $webform_submission->toUrl()->setAbsolute()->toString() . ')' . PHP_EOL;
+    }
+    return $text;
+  }
+  else {
+    $links = [];
+    foreach ($webform_submissions as $webform_submission) {
+      $links[] = $webform_submission->toLink()->toRenderable();
+    }
+
+    $t_args = [':href' => 'https://www.drupal.org/security/psa'];
+    $build = [
+      'title' => [
+        '#markup' => t('Invalid signature file detected and deleted. (@see <a href=":href">PSA-XXXXX</a>)', $t_args),
+      ],
+      'links' => [
+        '#theme' => 'item_list',
+        '#items' => $links,
+      ],
+    ];
+    return \Drupal::service('renderer')->renderPlain($build);
+  }
+}
diff --git a/web/modules/webform/js/webform.block.js b/web/modules/webform/js/webform.block.js
index 21deae1e79..c18aa1d23e 100644
--- a/web/modules/webform/js/webform.block.js
+++ b/web/modules/webform/js/webform.block.js
@@ -34,7 +34,7 @@
        *   A string with the summary.
        */
       function selectSummary(context) {
-        return $(context).find('#edit-visibility-webform-webforms option:selected').map(function () { return this.text; }).get().join(', ') || Drupal.t('Not restricted');
+        return $(context).find('#edit-visibility-webform-webforms option:selected').map(function () { return Drupal.checkPlain(this.text); }).get().join(', ') || Drupal.t('Not restricted');
       }
 
       $('[data-drupal-selector="edit-visibility-webform"]').drupalSetSummary(selectSummary);
diff --git a/web/modules/webform/js/webform.element.codemirror.js b/web/modules/webform/js/webform.element.codemirror.js
index 0e3f1ed99a..b149a1feb9 100644
--- a/web/modules/webform/js/webform.element.codemirror.js
+++ b/web/modules/webform/js/webform.element.codemirror.js
@@ -87,9 +87,14 @@
         }
 
         // Issue #2764443: CodeMirror is not setting submitted value when
-        // rendered within a webform UI dialog.
-        editor.on('blur', function (event) {
-          editor.save();
+        // rendered within a webform UI dialog or within an Ajaxified element.
+        var changeTimer = null;
+        editor.on('change', function () {
+          if (changeTimer) {
+            window.clearTimeout(changeTimer);
+            changeTimer = null;
+          }
+          changeTimer = setTimeout(function () {editor.save();}, 500);
         });
 
         // Update CodeMirror when the textarea's value has changed.
diff --git a/web/modules/webform/js/webform.element.date.js b/web/modules/webform/js/webform.element.date.js
index e9c9c81612..257698d9a8 100644
--- a/web/modules/webform/js/webform.element.date.js
+++ b/web/modules/webform/js/webform.element.date.js
@@ -99,7 +99,9 @@
         }
 
         // Disable autocomplete.
-        $input.attr('autocomplete', 'off');
+        // @see https://gist.github.com/niksumeiko/360164708c3b326bd1c8
+        var isChrome = (/chrom(e|ium)/.test(window.navigator.userAgent.toLowerCase()));
+        $input.attr('autocomplete', (isChrome) ? 'chrome-off-' + Math.floor(Math.random() * 100000000) : 'off');
 
         $input.datepicker(options);
       });
diff --git a/web/modules/webform/js/webform.element.inputhide.js b/web/modules/webform/js/webform.element.inputhide.js
index d06698939c..0a7acfd360 100644
--- a/web/modules/webform/js/webform.element.inputhide.js
+++ b/web/modules/webform/js/webform.element.inputhide.js
@@ -38,7 +38,7 @@
           $(this)
             .on('blur', function () {
               this.type = 'password';
-              $(this).attr('autocomplete', 'off');
+              $(this).attr('autocomplete', (isChrome) ? 'chrome-off-' + Math.floor(Math.random() * 100000000) : 'off');
             })
             .on('focus', function () {
               this.type = type;
diff --git a/web/modules/webform/js/webform.element.location.places.js b/web/modules/webform/js/webform.element.location.places.js
index 6a2bcbd642..f213d6ca95 100644
--- a/web/modules/webform/js/webform.element.location.places.js
+++ b/web/modules/webform/js/webform.element.location.places.js
@@ -64,7 +64,9 @@
         var placesAutocomplete = window.places(options);
 
         // Disable autocomplete.
-        $input.attr('autocomplete', 'off');
+        // @see https://gist.github.com/niksumeiko/360164708c3b326bd1c8
+        var isChrome = (/chrom(e|ium)/.test(window.navigator.userAgent.toLowerCase()));
+        $input.attr('autocomplete', (isChrome) ? 'chrome-off-' + Math.floor(Math.random() * 100000000) : 'off');
 
         // Sync values on change and clear events.
         placesAutocomplete.on('change', function (e) {
diff --git a/web/modules/webform/js/webform.element.rating.js b/web/modules/webform/js/webform.element.rating.js
index 627e646046..52a16fcbbb 100644
--- a/web/modules/webform/js/webform.element.rating.js
+++ b/web/modules/webform/js/webform.element.rating.js
@@ -32,6 +32,9 @@
           if (document.readyState === 'complete') {
             $rateit.rateit();
           }
+          else {
+            window.setTimeout(function () {$rateit.rateit();});
+          }
 
           // Update the RateIt widget when the input's value has changed.
           // @see webform.states.js
diff --git a/web/modules/webform/js/webform.element.states.js b/web/modules/webform/js/webform.element.states.js
index 26325fe0c7..856d805cf6 100644
--- a/web/modules/webform/js/webform.element.states.js
+++ b/web/modules/webform/js/webform.element.states.js
@@ -7,6 +7,8 @@
 
   'use strict';
 
+  var isChrome = (/chrom(e|ium)/.test(window.navigator.userAgent.toLowerCase()));
+
   /**
    * Element #states builder.
    *
@@ -46,7 +48,7 @@
               .removeClass('form-autocomplete');
           }
           // Always disable browser auto completion.
-          $value.attr('autocomplete', 'off');
+          $value.attr('autocomplete', (isChrome ? 'chrome-off-' + Math.floor(Math.random() * 100000000) : 'off'));
         }).change();
       });
 
diff --git a/web/modules/webform/js/webform.filter.js b/web/modules/webform/js/webform.filter.js
index b5b64b7591..66f2d8020a 100644
--- a/web/modules/webform/js/webform.filter.js
+++ b/web/modules/webform/js/webform.filter.js
@@ -50,9 +50,10 @@
         };
 
         if ($table.length) {
+          var isChrome = (/chrom(e|ium)/.test(window.navigator.userAgent.toLowerCase()));
           $filterRows = $table.find(sourceSelector);
           $input
-            .attr('autocomplete', 'off')
+            .attr('autocomplete', (isChrome) ? 'chrome-off-' + Math.floor(Math.random() * 100000000) : 'off')
             .on('keyup', debounce(filterElementList, 200))
             .keyup();
 
diff --git a/web/modules/webform/js/webform.form.js b/web/modules/webform/js/webform.form.js
index d4f136e18c..6af1f863d8 100644
--- a/web/modules/webform/js/webform.form.js
+++ b/web/modules/webform/js/webform.form.js
@@ -7,6 +7,8 @@
 
   'use strict';
 
+  var isChrome = (/chrom(e|ium)/.test(window.navigator.userAgent.toLowerCase()));
+
   /**
    * Remove single submit event listener.
    *
@@ -29,6 +31,23 @@
     }
   };
 
+  /**
+   * Autocomplete.
+   *
+   * @type {Drupal~behavior}
+   *
+   * @prop {Drupal~behaviorAttach} attach
+   *   Attaches the behavior for the webform autofocusing.
+   */
+  Drupal.behaviors.webformAutocomplete = {
+    attach: function (context) {
+      if (isChrome) {
+        $(context).find('.webform-submission-form input[autocomplete="off"]')
+          .attr('autocomplete', 'chrome-off-' + Math.floor(Math.random() * 100000000));
+      }
+    }
+  };
+
   /**
    * Prevent webform autosubmit on wizard pages.
    *
diff --git a/web/modules/webform/js/webform.states.js b/web/modules/webform/js/webform.states.js
index 62798111dd..3d84806d09 100644
--- a/web/modules/webform/js/webform.states.js
+++ b/web/modules/webform/js/webform.states.js
@@ -302,6 +302,12 @@
         .trigger('keydown', extraParameters)
         .trigger('keyup', extraParameters)
         .trigger('blur', extraParameters);
+
+      // Make sure input mask is reset when value is restored.
+      // @see https://www.drupal.org/project/webform/issues/3124155
+      if ($input.attr('data-inputmask-mask')) {
+        setTimeout(function () {$input.inputmask('remove').inputmask();});
+      }
     }
   }
 
diff --git a/web/modules/webform/modules/webform_access/src/WebformAccessGroupListBuilder.php b/web/modules/webform/modules/webform_access/src/WebformAccessGroupListBuilder.php
index 3d4bd2d7ce..2a04fcd2b7 100644
--- a/web/modules/webform/modules/webform_access/src/WebformAccessGroupListBuilder.php
+++ b/web/modules/webform/modules/webform_access/src/WebformAccessGroupListBuilder.php
@@ -88,6 +88,7 @@ public function render() {
     $build['table']['#attributes']['class'][] = 'webform-access-group-table';
 
     // Attachments.
+    $build['#attached']['library'][] = 'webform/webform.admin';
     $build['#attached']['library'][] = 'webform/webform.admin.dialog';
 
     return $build;
diff --git a/web/modules/webform/modules/webform_access/src/WebformAccessTypeListBuilder.php b/web/modules/webform/modules/webform_access/src/WebformAccessTypeListBuilder.php
index 03d58c6955..ce3fc48d1d 100644
--- a/web/modules/webform/modules/webform_access/src/WebformAccessTypeListBuilder.php
+++ b/web/modules/webform/modules/webform_access/src/WebformAccessTypeListBuilder.php
@@ -3,6 +3,7 @@
 namespace Drupal\webform_access;
 
 use Drupal\Core\Config\Entity\ConfigEntityListBuilder;
+use Drupal\Core\Config\Entity\ConfigEntityStorageInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
@@ -32,7 +33,7 @@ class WebformAccessTypeListBuilder extends ConfigEntityListBuilder {
   /**
    * {@inheritdoc}
    */
-  public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, WebformAccessGroupStorageInterface $access_group_storage) {
+  public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, ConfigEntityStorageInterface $access_group_storage) {
     parent::__construct($entity_type, $storage);
     $this->accessGroupStorage = $access_group_storage;
   }
diff --git a/web/modules/webform/modules/webform_access/webform_access.info.yml b/web/modules/webform/modules/webform_access/webform_access.info.yml
index c23e0dbc0f..ae01575fde 100644
--- a/web/modules/webform/modules/webform_access/webform_access.info.yml
+++ b/web/modules/webform/modules/webform_access/webform_access.info.yml
@@ -7,7 +7,7 @@ dependencies:
   - 'webform:webform'
   - 'webform:webform_node'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_access.yml b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_access.yml
index b2524ea046..50a528f980 100644
--- a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_access.yml
+++ b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_access.yml
@@ -160,6 +160,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -212,3 +213,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_email.yml b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_email.yml
index b84c17784a..d9900202e8 100644
--- a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_email.yml
+++ b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_email.yml
@@ -61,13 +61,13 @@ elements: |
             </SOURCE>
          </asx:values>
       </asx:abap>
-
+  
   attachment_twig:
     '#type': webform_attachment_twig
     '#title': attachment_twig
     '#filename': 'attachment_twig-[current-date:html_date].xml'
     '#template': "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<asx:abap xmlns:asx=\"http://www.sap.com/abapxml\" version=\"1.0\">\n   <asx:values>\n      <VERSION>1.0</VERSION>\n      <SENDER>{{ webform_id }}</SENDER>\n      <WEBFORM_ID>{{ data.email }}</WEBFORM_ID>\n      <SOURCE>\n        {% for key, value in data %}\n         <o2PARAVALU>\n            <NAME>{{ (elements_flattened[key]['#xml_name']) ? elements_flattened[key]['#xml_name'] : key }}</NAME>\n            <VALUE>{{ value }}</VALUE>\n         </o2PARAVALU>\n        {% endfor %}      \n      </SOURCE>\n   </asx:values>\n</asx:abap>"
-
+  
 css: ''
 javascript: ''
 settings:
@@ -181,6 +181,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -269,3 +270,4 @@ handlers:
       sender_name: ''
       theme_name: ''
       parameters: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_sanitize.yml b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_sanitize.yml
index 4dc071de7b..b4b5490eb7 100644
--- a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_sanitize.yml
+++ b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_sanitize.yml
@@ -140,6 +140,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -190,3 +191,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_states.yml b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_states.yml
index 11e59a0e5a..d3945c0f31 100644
--- a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_states.yml
+++ b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_states.yml
@@ -27,7 +27,7 @@ elements: |
       'enabled':
         ':input[name="attach"]':
           checked: true
-
+  
 css: ''
 javascript: ''
 settings:
@@ -141,6 +141,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -227,6 +228,7 @@ handlers:
       sender_name: ''
       theme_name: ''
       parameters: {  }
+variants: {  }
 uuid: 08971b54-57be-4bc9-956a-8cfa57c7cadd
 _core:
   default_config_hash: XUf67HS7kvhJPn6INGzCeH3OdEnQNm9Kb_H5o-HfYlQ
diff --git a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_token.yml b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_token.yml
index cb04db05c9..9583fe19ce 100644
--- a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_token.yml
+++ b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_token.yml
@@ -148,6 +148,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -198,3 +199,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_twig.yml b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_twig.yml
index 7e28e23641..2027f05b3f 100644
--- a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_twig.yml
+++ b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_twig.yml
@@ -150,6 +150,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -200,3 +201,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_url.yml b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_url.yml
index 9c149759fe..0e50a25591 100644
--- a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_url.yml
+++ b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_url.yml
@@ -151,6 +151,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -201,3 +202,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/webform_attachment_test.info.yml b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/webform_attachment_test.info.yml
index 28c08b95bd..d2886e34bb 100644
--- a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/webform_attachment_test.info.yml
+++ b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/webform_attachment_test.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform_attachment'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_attachment/webform_attachment.info.yml b/web/modules/webform/modules/webform_attachment/webform_attachment.info.yml
index 1388dc0689..e9b47ec95d 100644
--- a/web/modules/webform/modules/webform_attachment/webform_attachment.info.yml
+++ b/web/modules/webform/modules/webform_attachment/webform_attachment.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_bootstrap/tests/modules/webform_bootstrap_test_module/webform_bootstrap_test_module.info.yml b/web/modules/webform/modules/webform_bootstrap/tests/modules/webform_bootstrap_test_module/webform_bootstrap_test_module.info.yml
index 646898fd16..1e130c09d8 100644
--- a/web/modules/webform/modules/webform_bootstrap/tests/modules/webform_bootstrap_test_module/webform_bootstrap_test_module.info.yml
+++ b/web/modules/webform/modules/webform_bootstrap/tests/modules/webform_bootstrap_test_module/webform_bootstrap_test_module.info.yml
@@ -8,7 +8,7 @@ dependencies:
   - 'webform:webform'
   - 'webform:webform_bootstrap'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_bootstrap/tests/themes/webform_bootstrap_test_theme/webform_bootstrap_test_theme.info.yml b/web/modules/webform/modules/webform_bootstrap/tests/themes/webform_bootstrap_test_theme/webform_bootstrap_test_theme.info.yml
index ad7ba9a59e..a40f1da74d 100644
--- a/web/modules/webform/modules/webform_bootstrap/tests/themes/webform_bootstrap_test_theme/webform_bootstrap_test_theme.info.yml
+++ b/web/modules/webform/modules/webform_bootstrap/tests/themes/webform_bootstrap_test_theme/webform_bootstrap_test_theme.info.yml
@@ -22,7 +22,7 @@ regions:
 libraries:
   - 'webform_bootstrap_test_theme/global-styling'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_bootstrap/webform_bootstrap.info.yml b/web/modules/webform/modules/webform_bootstrap/webform_bootstrap.info.yml
index b7d74f1084..d3ec490d9f 100644
--- a/web/modules/webform/modules/webform_bootstrap/webform_bootstrap.info.yml
+++ b/web/modules/webform/modules/webform_bootstrap/webform_bootstrap.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application.yml b/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application.yml
index 9efaf1bdaa..d77827b5ad 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application.yml
+++ b/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application.yml
@@ -157,6 +157,7 @@ elements: |
       '#access_update_roles': {  }
       '#access_view_roles':
         - authenticated
+  
 css: ''
 javascript: ''
 settings:
@@ -270,6 +271,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -321,3 +323,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application_evaluation.yml b/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application_evaluation.yml
index f9472e63d6..02541abe05 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application_evaluation.yml
+++ b/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application_evaluation.yml
@@ -25,12 +25,12 @@ elements: |
       {{ children }}
       <div>{{ 'Submitted by'|t }}: <em>[webform_submission:user]</em></div>
       <hr/>
-
+  
     '#format_text': |
       {{ children }}
       {{ 'Submitted by'|t }} [webform_submission:user]
       ------------------------------------------------------------
-
+  
     rating:
       '#type': webform_rating
       '#title': Rating
@@ -38,6 +38,7 @@ elements: |
     comments:
       '#type': textarea
       '#title': Comments
+  
 css: ''
 javascript: ''
 settings:
@@ -151,6 +152,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -201,3 +203,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/webform_demo_application_evaluation.info.yml b/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/webform_demo_application_evaluation.info.yml
index 0ce168cb40..af0b3c9be5 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/webform_demo_application_evaluation.info.yml
+++ b/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/webform_demo_application_evaluation.info.yml
@@ -9,7 +9,7 @@ dependencies:
   - 'webform:webform'
   - 'webform:webform_node'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/webform_demo_application_evaluation.module b/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/webform_demo_application_evaluation.module
index 37220b8808..e488c76dea 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/webform_demo_application_evaluation.module
+++ b/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/webform_demo_application_evaluation.module
@@ -66,7 +66,7 @@ function webform_demo_application_evaluation_webform_submission_delete(WebformSu
  */
 function _webform_demo_application_evaluation_calculate_evaluation_rating(WebformSubmissionInterface $webform_submission) {
   $webform = $webform_submission->getWebform();
-  if ($webform->id() !== 'demo_application_evaluation') {
+  if (!$webform || $webform->id() !== 'demo_application_evaluation') {
     return;
   }
 
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_event_registration/config/install/webform.webform.demo_event_registration.yml b/web/modules/webform/modules/webform_demo/webform_demo_event_registration/config/install/webform.webform.demo_event_registration.yml
index 64b4bb6361..082ee871ea 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_event_registration/config/install/webform.webform.demo_event_registration.yml
+++ b/web/modules/webform/modules/webform_demo/webform_demo_event_registration/config/install/webform.webform.demo_event_registration.yml
@@ -60,7 +60,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': Register
-
+  
 css: ''
 javascript: ''
 settings:
@@ -174,6 +174,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -332,3 +333,4 @@ handlers:
       option_unlimited_message: '[Unlimited]'
       option_none_message: ''
       option_error_message: 'Tee shirts in @label are no longer available.'
+variants: {  }
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_event_registration/webform_demo_event_registration.info.yml b/web/modules/webform/modules/webform_demo/webform_demo_event_registration/webform_demo_event_registration.info.yml
index 4ef936ed11..96e341e848 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_event_registration/webform_demo_event_registration.info.yml
+++ b/web/modules/webform/modules/webform_demo/webform_demo_event_registration/webform_demo_event_registration.info.yml
@@ -12,7 +12,7 @@ dependencies:
   - 'webform:webform_scheduled_email'
   - 'webform:webform_options_limit'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_group/config/install/webform.webform.webform_group_contact.yml b/web/modules/webform/modules/webform_demo/webform_demo_group/config/install/webform.webform.webform_group_contact.yml
index 73a4db9e45..10bf658ead 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_group/config/install/webform.webform.webform_group_contact.yml
+++ b/web/modules/webform/modules/webform_demo/webform_demo_group/config/install/webform.webform.webform_group_contact.yml
@@ -1,12 +1,9 @@
-uuid: 6f8e252a-8dee-4d99-8362-77b02dcf54d1
 langcode: en
 status: open
 dependencies:
   enforced:
     module:
       - webform_demo_group
-_core:
-  default_config_hash: ibrQM-l73s998t710tfXCiZlMT_13oFxxPmVh7tBHIk
 open: null
 close: null
 weight: 0
@@ -89,6 +86,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': 'Send message'
+  
 css: ''
 javascript: ''
 settings:
@@ -202,6 +200,8 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
+  token_view: false
   token_update: false
 access:
   create:
@@ -341,3 +341,7 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
+uuid: 6f8e252a-8dee-4d99-8362-77b02dcf54d1
+_core:
+  default_config_hash: ibrQM-l73s998t710tfXCiZlMT_13oFxxPmVh7tBHIk
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_group/webform_demo_group.info.yml b/web/modules/webform/modules/webform_demo/webform_demo_group/webform_demo_group.info.yml
index 4fe8d8d6b0..d226e4a28b 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_group/webform_demo_group.info.yml
+++ b/web/modules/webform/modules/webform_demo/webform_demo_group/webform_demo_group.info.yml
@@ -11,7 +11,7 @@ dependencies:
   - 'webform:webform_node'
   - 'webform:webform_group'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_region_contact/config/install/webform.webform.demo_region_contact.yml b/web/modules/webform/modules/webform_demo/webform_demo_region_contact/config/install/webform.webform.demo_region_contact.yml
index 4dbdd1f16f..f8b92068fb 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_region_contact/config/install/webform.webform.demo_region_contact.yml
+++ b/web/modules/webform/modules/webform_demo/webform_demo_region_contact/config/install/webform.webform.demo_region_contact.yml
@@ -39,7 +39,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': 'Send message'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -153,6 +153,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -419,3 +420,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_region_contact/webform_demo_region_contact.info.yml b/web/modules/webform/modules/webform_demo/webform_demo_region_contact/webform_demo_region_contact.info.yml
index fa28927957..e119f357ae 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_region_contact/webform_demo_region_contact.info.yml
+++ b/web/modules/webform/modules/webform_demo/webform_demo_region_contact/webform_demo_region_contact.info.yml
@@ -10,7 +10,7 @@ dependencies:
   - 'webform:webform_node'
   - 'webform:webform_access'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntityFormApiBaseForm.php b/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntityFormApiBaseForm.php
index 3d580b22f5..35a415d356 100644
--- a/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntityFormApiBaseForm.php
+++ b/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntityFormApiBaseForm.php
@@ -141,7 +141,7 @@ protected function renderExport(array $form, $prefix = '$form') {
             $element_children[$property] = $value;
           }
           elseif ($this->isPropertyTranslatable($property)) {
-            $element_export[$property] = '<T>' . $value . '</T>';
+            $element_export[$property] = $this->wrapTranslatableValue($value);
           }
           else {
             $element_export[$property] = $value;
@@ -162,6 +162,27 @@ protected function renderExport(array $form, $prefix = '$form') {
     return $output;
   }
 
+  /**
+   * Wrap translatable value in <T> tags.
+   *
+   * @param mixed $value
+   *   A translatable value.
+   *
+   * @return array|string
+   *   A translatable value in <T> tags.
+   */
+  protected function wrapTranslatableValue($value) {
+    if (is_array($value)) {
+      foreach ($value as $key => $item) {
+        $value[$key] = $this->wrapTranslatableValue($item);
+      }
+      return $value;
+    }
+    else {
+       return '<T>' . $value . '</T>';
+    }
+  }
+
   /**
    * Determine if an element property is translatable.
    *
diff --git a/web/modules/webform/modules/webform_devel/webform_devel.info.yml b/web/modules/webform/modules/webform_devel/webform_devel.info.yml
index 678a918459..c29ebb0eaa 100644
--- a/web/modules/webform/modules/webform_devel/webform_devel.info.yml
+++ b/web/modules/webform/modules/webform_devel/webform_devel.info.yml
@@ -7,7 +7,7 @@ dependencies:
   - 'devel:devel'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_editorial/webform_editorial.info.yml b/web/modules/webform/modules/webform_editorial/webform_editorial.info.yml
index 98662be802..1fbd63d3db 100644
--- a/web/modules/webform/modules/webform_editorial/webform_editorial.info.yml
+++ b/web/modules/webform/modules/webform_editorial/webform_editorial.info.yml
@@ -3,11 +3,12 @@ type: module
 description: 'Provides editorial management tools for the Webform module.'
 package: Webform
 core_version_requirement: ^8.7.7 || ^9
+configure: webform_editorial.index
 hidden: true
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/config/install/webform.webform.test_entity_print.yml b/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/config/install/webform.webform.test_entity_print.yml
index 5dda4f7843..e8cfc14deb 100644
--- a/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/config/install/webform.webform.test_entity_print.yml
+++ b/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/config/install/webform.webform.test_entity_print.yml
@@ -132,6 +132,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -182,3 +183,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/config/install/webform.webform.test_entity_print_custom.yml b/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/config/install/webform.webform.test_entity_print_custom.yml
index 8f9be3a8ed..841a889929 100644
--- a/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/config/install/webform.webform.test_entity_print_custom.yml
+++ b/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/config/install/webform.webform.test_entity_print_custom.yml
@@ -132,6 +132,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -182,6 +183,7 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
 third_party_settings:
   webform_entity_print:
     template:
diff --git a/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/webform_entity_print_test.info.yml b/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/webform_entity_print_test.info.yml
index ae4ab39134..b5fcb29f14 100644
--- a/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/webform_entity_print_test.info.yml
+++ b/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/webform_entity_print_test.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform_entity_print'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_entity_print/webform_entity_print.info.yml b/web/modules/webform/modules/webform_entity_print/webform_entity_print.info.yml
index 39ba5b59b6..464fe905ad 100644
--- a/web/modules/webform/modules/webform_entity_print/webform_entity_print.info.yml
+++ b/web/modules/webform/modules/webform_entity_print/webform_entity_print.info.yml
@@ -7,7 +7,7 @@ dependencies:
   - 'webform:webform'
   - 'entity_print:entity_print'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_entity_print_attachment/tests/modules/webform_entity_print_attachment_test/config/install/webform.webform.test_entity_print_attachment.yml b/web/modules/webform/modules/webform_entity_print_attachment/tests/modules/webform_entity_print_attachment_test/config/install/webform.webform.test_entity_print_attachment.yml
index a4973c7c20..5937705a44 100644
--- a/web/modules/webform/modules/webform_entity_print_attachment/tests/modules/webform_entity_print_attachment_test/config/install/webform.webform.test_entity_print_attachment.yml
+++ b/web/modules/webform/modules/webform_entity_print_attachment/tests/modules/webform_entity_print_attachment_test/config/install/webform.webform.test_entity_print_attachment.yml
@@ -33,7 +33,7 @@ elements: |
     '#display_on': both
     '#view_mode': twig
     '#template': '{This is a custom template}'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -147,6 +147,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -233,3 +234,4 @@ handlers:
       sender_name: ''
       theme_name: ''
       parameters: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_entity_print_attachment/tests/modules/webform_entity_print_attachment_test/webform_entity_print_attachment_test.info.yml b/web/modules/webform/modules/webform_entity_print_attachment/tests/modules/webform_entity_print_attachment_test/webform_entity_print_attachment_test.info.yml
index 778d5d51c5..64d106192f 100644
--- a/web/modules/webform/modules/webform_entity_print_attachment/tests/modules/webform_entity_print_attachment_test/webform_entity_print_attachment_test.info.yml
+++ b/web/modules/webform/modules/webform_entity_print_attachment/tests/modules/webform_entity_print_attachment_test/webform_entity_print_attachment_test.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform_entity_print_attachment'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_entity_print_attachment/webform_entity_print_attachment.info.yml b/web/modules/webform/modules/webform_entity_print_attachment/webform_entity_print_attachment.info.yml
index 998be2b163..4d261d1f3c 100644
--- a/web/modules/webform/modules/webform_entity_print_attachment/webform_entity_print_attachment.info.yml
+++ b/web/modules/webform/modules/webform_entity_print_attachment/webform_entity_print_attachment.info.yml
@@ -7,7 +7,7 @@ dependencies:
   - 'webform:webform_attachment'
   - 'webform:webform_entity_print'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_example_composite/config/install/webform.webform.webform_example_composite.yml b/web/modules/webform/modules/webform_example_composite/config/install/webform.webform.webform_example_composite.yml
index 2b4626bc5c..78d833c4c6 100644
--- a/web/modules/webform/modules/webform_example_composite/config/install/webform.webform.webform_example_composite.yml
+++ b/web/modules/webform/modules/webform_example_composite/config/install/webform.webform.webform_example_composite.yml
@@ -137,6 +137,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -187,3 +188,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_example_composite/webform_example_composite.info.yml b/web/modules/webform/modules/webform_example_composite/webform_example_composite.info.yml
index f167fd6081..436e7fc393 100644
--- a/web/modules/webform/modules/webform_example_composite/webform_example_composite.info.yml
+++ b/web/modules/webform/modules/webform_example_composite/webform_example_composite.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_example_custom_form/config/install/webform.webform.webform_example_custom_form.yml b/web/modules/webform/modules/webform_example_custom_form/config/install/webform.webform.webform_example_custom_form.yml
index 3eca1ff822..ba61a1dda0 100644
--- a/web/modules/webform/modules/webform_example_custom_form/config/install/webform.webform.webform_example_custom_form.yml
+++ b/web/modules/webform/modules/webform_example_custom_form/config/install/webform.webform.webform_example_custom_form.yml
@@ -303,7 +303,7 @@ elements: |
           last_name: Smith
         - first_name: Jane
           last_name: Doe
-
+  
 css: ''
 javascript: ''
 settings:
@@ -417,6 +417,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -467,3 +468,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_example_custom_form/webform_example_custom_form.info.yml b/web/modules/webform/modules/webform_example_custom_form/webform_example_custom_form.info.yml
index cae644f311..aa0fde811c 100644
--- a/web/modules/webform/modules/webform_example_custom_form/webform_example_custom_form.info.yml
+++ b/web/modules/webform/modules/webform_example_custom_form/webform_example_custom_form.info.yml
@@ -8,7 +8,7 @@ dependencies:
   - 'webform:webform'
   - 'webform:webform_devel'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_example_element/config/install/webform.webform.webform_example_element.yml b/web/modules/webform/modules/webform_example_element/config/install/webform.webform.webform_example_element.yml
index 02df99b896..8f7ed20f6e 100644
--- a/web/modules/webform/modules/webform_example_element/config/install/webform.webform.webform_example_element.yml
+++ b/web/modules/webform/modules/webform_example_element/config/install/webform.webform.webform_example_element.yml
@@ -136,6 +136,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -186,3 +187,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_example_element/webform_example_element.info.yml b/web/modules/webform/modules/webform_example_element/webform_example_element.info.yml
index 6d9417f401..449708a7b0 100644
--- a/web/modules/webform/modules/webform_example_element/webform_example_element.info.yml
+++ b/web/modules/webform/modules/webform_example_element/webform_example_element.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_example_element_properties/webform_example_element_properties.info.yml b/web/modules/webform/modules/webform_example_element_properties/webform_example_element_properties.info.yml
index 8d93ddd3b6..d05e42aa22 100644
--- a/web/modules/webform/modules/webform_example_element_properties/webform_example_element_properties.info.yml
+++ b/web/modules/webform/modules/webform_example_element_properties/webform_example_element_properties.info.yml
@@ -7,7 +7,7 @@ dependencies:
   - 'webform:webform'
   - 'webform:webform_ui'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_example_handler/config/install/webform.webform.webform_example_handler.yml b/web/modules/webform/modules/webform_example_handler/config/install/webform.webform.webform_example_handler.yml
index 51b162706c..7fff2615a3 100644
--- a/web/modules/webform/modules/webform_example_handler/config/install/webform.webform.webform_example_handler.yml
+++ b/web/modules/webform/modules/webform_example_handler/config/install/webform.webform.webform_example_handler.yml
@@ -136,6 +136,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -196,3 +197,4 @@ handlers:
     settings:
       message: 'You entered: <code>[webform_submission:values:value]</code>'
       debug: false
+variants: {  }
diff --git a/web/modules/webform/modules/webform_example_handler/webform_example_handler.info.yml b/web/modules/webform/modules/webform_example_handler/webform_example_handler.info.yml
index 902ccf7af2..e8c26f8a3a 100644
--- a/web/modules/webform/modules/webform_example_handler/webform_example_handler.info.yml
+++ b/web/modules/webform/modules/webform_example_handler/webform_example_handler.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_example_remote_post/config/install/webform.webform.example_remote_post.yml b/web/modules/webform/modules/webform_example_remote_post/config/install/webform.webform.example_remote_post.yml
index 4b2369b47a..debc224bf4 100644
--- a/web/modules/webform/modules/webform_example_remote_post/config/install/webform.webform.example_remote_post.yml
+++ b/web/modules/webform/modules/webform_example_remote_post/config/install/webform.webform.example_remote_post.yml
@@ -39,7 +39,7 @@ elements: |
     '#title': 'Confirmation number'
     '#type': value
     '#value': '[webform:handler:remote_post:completed:confirmation_number]'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -130,7 +130,7 @@ settings:
   confirmation_title: ''
   confirmation_message: |
     <p>Your confirmation number is [webform_submission:values:confirmation_number].</p>
-
+    
   confirmation_url: ''
   confirmation_attributes: {  }
   confirmation_back: true
@@ -155,6 +155,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -237,22 +238,22 @@ handlers:
         confirmation_number: confirmation_number
       custom_data: |
         custom_all: true
-
+        
       custom_options: ''
       cast: false
       debug: true
       completed_url: '[site:url]webform_example_remote_post/completed'
       completed_custom_data: |
         custom_completed: true
-
+        
       updated_url: '[site:url]webform_example_remote_post/updated'
       updated_custom_data: |
         custom_updated: true
-
+        
       deleted_url: '[site:url]webform_example_remote_post/deleted'
       deleted_custom_data: |
         custom_deleted: true
-
+        
       draft_created_url: ''
       draft_created_custom_data: ''
       draft_updated_url: ''
@@ -262,3 +263,4 @@ handlers:
       message: ''
       messages: {  }
       error_url: ''
+variants: {  }
diff --git a/web/modules/webform/modules/webform_example_remote_post/webform_example_remote_post.info.yml b/web/modules/webform/modules/webform_example_remote_post/webform_example_remote_post.info.yml
index 1699b15929..75a138718b 100644
--- a/web/modules/webform/modules/webform_example_remote_post/webform_example_remote_post.info.yml
+++ b/web/modules/webform/modules/webform_example_remote_post/webform_example_remote_post.info.yml
@@ -7,7 +7,7 @@ dependencies:
   - 'token:token'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_example_variant/config/install/webform.webform.webform_example_variant_ab_test.yml b/web/modules/webform/modules/webform_example_variant/config/install/webform.webform.webform_example_variant_ab_test.yml
index 49e5e804f8..49887c04ec 100644
--- a/web/modules/webform/modules/webform_example_variant/config/install/webform.webform.webform_example_variant_ab_test.yml
+++ b/web/modules/webform/modules/webform_example_variant/config/install/webform.webform.webform_example_variant_ab_test.yml
@@ -45,7 +45,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': 'Submit feedback'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -159,6 +159,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -316,7 +317,7 @@ variants:
           '#title_display': 'inline'
         actions:
           '#title': 'Submit'
-
+        
       handlers:
         email_confirmation:
           status: false
diff --git a/web/modules/webform/modules/webform_example_variant/config/install/webform.webform.webform_example_variant_segments.yml b/web/modules/webform/modules/webform_example_variant/config/install/webform.webform.webform_example_variant_segments.yml
index f9f2a9767b..06a2749e9b 100644
--- a/web/modules/webform/modules/webform_example_variant/config/install/webform.webform.webform_example_variant_segments.yml
+++ b/web/modules/webform/modules/webform_example_variant/config/install/webform.webform.webform_example_variant_segments.yml
@@ -33,6 +33,7 @@ elements: |
   notes:
     '#type': textfield
     '#title': Notes
+  
 css: ''
 javascript: ''
 settings:
@@ -146,6 +147,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
diff --git a/web/modules/webform/modules/webform_example_variant/webform_example_variant.info.yml b/web/modules/webform/modules/webform_example_variant/webform_example_variant.info.yml
index 419ac28550..6bce61f4eb 100644
--- a/web/modules/webform/modules/webform_example_variant/webform_example_variant.info.yml
+++ b/web/modules/webform/modules/webform_example_variant/webform_example_variant.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_computed_elements.yml b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_computed_elements.yml
index 78ccf28d68..72bdd8bd8b 100644
--- a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_computed_elements.yml
+++ b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_computed_elements.yml
@@ -46,7 +46,7 @@ elements: |
           Hello {{ data.first_name }} {{ data.last_name }}!!!
         </h2>
         <p>You are {{ ('now'|date('Y')) - (data.date_of_birth|date('Y'))  }} years old.</p>
-
+  
 css: ''
 javascript: ''
 settings:
@@ -160,6 +160,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -210,3 +211,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_computed_elements_ajax.yml b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_computed_elements_ajax.yml
index e37b33a75c..3a5ee98eea 100644
--- a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_computed_elements_ajax.yml
+++ b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_computed_elements_ajax.yml
@@ -227,6 +227,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -277,3 +278,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_element_states.yml b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_element_states.yml
index edf134fdec..e41084ca6e 100644
--- a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_element_states.yml
+++ b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_element_states.yml
@@ -305,6 +305,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -355,3 +356,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_flexbox_layout.yml b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_flexbox_layout.yml
index 6f5422a70e..1e09a09bef 100644
--- a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_flexbox_layout.yml
+++ b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_flexbox_layout.yml
@@ -231,6 +231,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -281,3 +282,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_input_masks.yml b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_input_masks.yml
index 034cb566f7..aa9b18a471 100644
--- a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_input_masks.yml
+++ b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_input_masks.yml
@@ -199,6 +199,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -249,3 +250,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_style_guide.yml b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_style_guide.yml
index 7a85c6911c..c56ea8d825 100644
--- a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_style_guide.yml
+++ b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_style_guide.yml
@@ -94,7 +94,7 @@ elements: |
         three: Three
     radios_buttons:
       '#type': radios
-      '#title': Radios (Buttons)
+      '#title': 'Radios (Buttons)'
       '#options_display': buttons
       '#options':
         one: One
@@ -232,6 +232,13 @@ elements: |
     webform_rating:
       '#type': webform_rating
       '#title': Rating
+    webform_scale:
+      '#type': webform_scale
+      '#title': Scale
+      '#min': 1
+      '#max': 10
+      '#min_text': '1 = disagree'
+      '#max_text': '10 = agree'
     webform_signature:
       '#type': webform_signature
       '#title': Signature
@@ -334,18 +341,18 @@ elements: |
     '#open': true
     webform_addresses:
       '#type': fieldset
-      '#title': 'Addresses'
+      '#title': Addresses
       webform_address:
         '#type': webform_address
-        '#title': First address
+        '#title': 'First address'
         '#flexbox': false
         '#title_display': above
       webform_same_address:
         '#type': webform_same
-        '#title': Second address same as the first address
+        '#title': 'Second address same as the first address'
         '#source': webform_address
         '#destination': webform_address_other
-        '#destination_state': 'visible-slide'
+        '#destination_state': visible-slide
         '#default_value': true
       webform_address_other:
         '#type': webform_address
@@ -485,6 +492,75 @@ elements: |
       '#wrapper_attributes':
         class:
           - 'container-inline clearfix'
+    table:
+      '#type': webform_table
+      '#title': Table
+      '#header':
+        - title: 'First Name'
+          attributes:
+            style: 'width: 40%'
+        - title: 'Last Name'
+          attributes:
+            style: 'width: 40%'
+        - title: Gender
+          attributes:
+            style: 'width: 20%'
+      table_01:
+        '#type': webform_table_row
+        '#title': 'Person (1)'
+        table_01_first_name:
+          '#type': textfield
+          '#title': 'First name (1)'
+          '#title_display': invisible
+        table_01_last_name:
+          '#type': textfield
+          '#title': 'Last name (1)'
+          '#title_display': invisible
+        table_01_gender:
+          '#type': select
+          '#title': 'Gender (1)'
+          '#title_display': invisible
+          '#options': gender
+      table_02:
+        '#type': webform_table_row
+        '#title': 'Person (2)'
+        '#states':
+          visible:
+            ':input[name="table_01_first_name"]':
+              filled: true
+        table_02_first_name:
+          '#type': textfield
+          '#title': 'First name (2)'
+          '#title_display': invisible
+        table_02_last_name:
+          '#type': textfield
+          '#title': 'Last name (2)'
+          '#title_display': invisible
+        table_02_gender:
+          '#type': select
+          '#title': 'Gender (2)'
+          '#title_display': invisible
+          '#options': gender
+      table_03:
+        '#type': webform_table_row
+        '#title': 'Person (3)'
+        '#states':
+          visible:
+            ':input[name="table_02_first_name"]':
+              filled: true
+        table_03_first_name:
+          '#type': textfield
+          '#title': 'First name (3)'
+          '#title_display': invisible
+        table_03_last_name:
+          '#type': textfield
+          '#title': 'Last name (3)'
+          '#title_display': invisible
+        table_03_gender:
+          '#type': select
+          '#title': 'Gender (3)'
+          '#title_display': invisible
+          '#options': gender
   dividers:
     '#type': details
     '#title': Dividers
@@ -681,6 +757,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -731,3 +808,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_wizard.yml b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_wizard.yml
index cb111be73a..8b81393c65 100644
--- a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_wizard.yml
+++ b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_wizard.yml
@@ -169,6 +169,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -219,3 +220,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_examples/webform_examples.info.yml b/web/modules/webform/modules/webform_examples/webform_examples.info.yml
index b114759c5f..eb18870962 100644
--- a/web/modules/webform/modules/webform_examples/webform_examples.info.yml
+++ b/web/modules/webform/modules/webform_examples/webform_examples.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_advanced.yml b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_advanced.yml
index 66d8b1c3c4..e25473f6f4 100644
--- a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_advanced.yml
+++ b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_advanced.yml
@@ -323,6 +323,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -373,3 +374,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_basic.yml b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_basic.yml
index b1867a9f06..d198162892 100644
--- a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_basic.yml
+++ b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_basic.yml
@@ -239,6 +239,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -289,3 +290,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_containers.yml b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_containers.yml
index 27579f2216..fc3dc4a40f 100644
--- a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_containers.yml
+++ b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_containers.yml
@@ -164,6 +164,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -214,3 +215,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_labels.yml b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_labels.yml
index 52af9250b0..98b268ec57 100644
--- a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_labels.yml
+++ b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_labels.yml
@@ -294,6 +294,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -344,3 +345,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_wizard.yml b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_wizard.yml
index 0b73f1bb00..a72b73d52b 100644
--- a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_wizard.yml
+++ b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_wizard.yml
@@ -169,6 +169,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -219,3 +220,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_examples_accessibility/webform_examples_accessibility.info.yml b/web/modules/webform/modules/webform_examples_accessibility/webform_examples_accessibility.info.yml
index 670c361ad9..fe25f96e5d 100644
--- a/web/modules/webform/modules/webform_examples_accessibility/webform_examples_accessibility.info.yml
+++ b/web/modules/webform/modules/webform_examples_accessibility/webform_examples_accessibility.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'drupal:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/config/install/webform.webform.test_element_group_roles.yml b/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/config/install/webform.webform.test_element_group_roles.yml
index 78f4d4d6f6..00226cf7e8 100644
--- a/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/config/install/webform.webform.test_element_group_roles.yml
+++ b/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/config/install/webform.webform.test_element_group_roles.yml
@@ -25,6 +25,7 @@ elements: |
     '#include_internal': false
     '#include_user_roles': true
     '#include_anonymous': true
+  
 css: ''
 javascript: ''
 settings:
@@ -138,6 +139,8 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
+  token_view: false
   token_update: false
 access:
   create:
@@ -195,3 +198,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/config/install/webform.webform.test_group_element_access.yml b/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/config/install/webform.webform.test_group_element_access.yml
index e4d00efe04..201affec04 100644
--- a/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/config/install/webform.webform.test_group_element_access.yml
+++ b/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/config/install/webform.webform.test_group_element_access.yml
@@ -43,6 +43,7 @@ elements: |
     '#access_create_roles': {  }
     '#access_create_group_roles':
       - custom
+  
 css: ''
 javascript: ''
 settings:
@@ -156,6 +157,8 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
+  token_view: false
   token_update: false
 access:
   create:
@@ -213,3 +216,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/webform_group_test.info.yml b/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/webform_group_test.info.yml
index 32335a2e4a..ba12a607a1 100644
--- a/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/webform_group_test.info.yml
+++ b/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/webform_group_test.info.yml
@@ -7,7 +7,7 @@ dependencies:
   - 'webform:webform_group'
   - 'group:group_test_config'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_group/webform_group.info.yml b/web/modules/webform/modules/webform_group/webform_group.info.yml
index 67b62c1515..77d971dbbc 100644
--- a/web/modules/webform/modules/webform_group/webform_group.info.yml
+++ b/web/modules/webform/modules/webform_group/webform_group.info.yml
@@ -10,7 +10,7 @@ dependencies:
   - 'group:group'
   - 'group:gnode'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/config/install/webform.webform.test_element_icheck.yml b/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/config/install/webform.webform.test_element_icheck.yml
index 8f60bb15d7..4444ca2bbd 100644
--- a/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/config/install/webform.webform.test_element_icheck.yml
+++ b/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/config/install/webform.webform.test_element_icheck.yml
@@ -97,7 +97,7 @@ elements: |
         enabled:
           ':input[name="checkboxes_trigger"]':
             filled: true
-
+  
 css: ''
 javascript: ''
 settings:
@@ -211,6 +211,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -261,3 +262,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/config/install/webform.webform.test_element_icheck_styles.yml b/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/config/install/webform.webform.test_element_icheck_styles.yml
index c9e04d9960..244042ec21 100644
--- a/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/config/install/webform.webform.test_element_icheck_styles.yml
+++ b/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/config/install/webform.webform.test_element_icheck_styles.yml
@@ -831,7 +831,7 @@ elements: |
         three: Three
       '#default_value': one
       '#icheck': square-aero
-
+  
 css: ''
 javascript: ''
 settings:
@@ -945,6 +945,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -995,3 +996,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/webform_icheck_test.info.yml b/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/webform_icheck_test.info.yml
index 8ec0dcb461..e08bf30b10 100644
--- a/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/webform_icheck_test.info.yml
+++ b/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/webform_icheck_test.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform_icheck'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_icheck/webform_icheck.info.yml b/web/modules/webform/modules/webform_icheck/webform_icheck.info.yml
index 484ac39d7d..e3c7dc44ca 100644
--- a/web/modules/webform/modules/webform_icheck/webform_icheck.info.yml
+++ b/web/modules/webform/modules/webform_icheck/webform_icheck.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_image_select/src/Element/WebformImageSelect.php b/web/modules/webform/modules/webform_image_select/src/Element/WebformImageSelect.php
index df5bf97ab7..cd4a2f0e6c 100644
--- a/web/modules/webform/modules/webform_image_select/src/Element/WebformImageSelect.php
+++ b/web/modules/webform/modules/webform_image_select/src/Element/WebformImageSelect.php
@@ -4,9 +4,9 @@
 
 use Drupal\Component\Serialization\Json;
 use Drupal\Component\Utility\Html;
-use Drupal\Component\Utility\Xss;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element\Select;
+use Drupal\webform\Element\WebformHtmlEditor;
 use Drupal\webform\Utility\WebformElementHelper;
 
 /**
@@ -139,8 +139,9 @@ public static function setOptions(array &$element) {
       foreach ($element['#images'] as $value => &$image) {
         if (isset($image['text'])) {
           // Apply XSS filter to image text.
-          $image['text'] = Xss::filter($image['text']);
-          $options[$value] = $image['text'];
+          $image['text'] = WebformHtmlEditor::stripTags($image['text']);
+          // Strip all HTML tags from the option.
+          $options[$value] = strip_tags($image['text']);
         }
         else {
           $options[$value] = $value;
diff --git a/web/modules/webform/modules/webform_image_select/src/WebformImageSelectImagesForm.php b/web/modules/webform/modules/webform_image_select/src/WebformImageSelectImagesForm.php
index 13bbd20d4f..61f56f214f 100644
--- a/web/modules/webform/modules/webform_image_select/src/WebformImageSelectImagesForm.php
+++ b/web/modules/webform/modules/webform_image_select/src/WebformImageSelectImagesForm.php
@@ -9,12 +9,29 @@
 use Drupal\webform\Utility\WebformDialogHelper;
 use Drupal\webform\Utility\WebformOptionsHelper;
 use Drupal\webform\Utility\WebformArrayHelper;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Provides a form to set webform image select images.
  */
 class WebformImageSelectImagesForm extends EntityForm {
 
+  /**
+   * Module extension list.
+   *
+   * @var \Drupal\Core\Extension\ModuleExtensionList
+   */
+  protected $moduleExtensionList;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    $instance = parent::create($container);
+    $instance->moduleExtensionList = $container->get('extension.list.module');
+    return $instance;
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -110,7 +127,7 @@ public function form(array $form, FormStateInterface $form_state) {
     if (!$webform_images->isNew()) {
       $hook_name = 'webform_image_select_images_' . $webform_images->id() . '_alter';
       $alter_hooks = $this->moduleHandler->getImplementations($hook_name);
-      $module_info = system_get_info('module');
+      $module_info = $this->moduleExtensionList->getAllInstalledInfo();
       $module_names = [];
       foreach ($alter_hooks as $options_alter_hook) {
         $module_name = str_replace($hook_name, '', $options_alter_hook);
diff --git a/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/config/install/webform.webform.test_element_image_select.yml b/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/config/install/webform.webform.test_element_image_select.yml
index c7969db201..e5fe8c1810 100644
--- a/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/config/install/webform.webform.test_element_image_select.yml
+++ b/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/config/install/webform.webform.test_element_image_select.yml
@@ -277,6 +277,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -327,3 +328,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/config/install/webform.webform.test_element_images.yml b/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/config/install/webform.webform.test_element_images.yml
index bc048ff0fe..9b24b179dc 100644
--- a/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/config/install/webform.webform.test_element_images.yml
+++ b/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/config/install/webform.webform.test_element_images.yml
@@ -178,6 +178,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -236,3 +237,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/webform_image_select_test.info.yml b/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/webform_image_select_test.info.yml
index 604e55025c..926e46e83a 100644
--- a/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/webform_image_select_test.info.yml
+++ b/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/webform_image_select_test.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform_image_select'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_image_select/tests/src/Functional/WebformImageSelectElementTest.php b/web/modules/webform/modules/webform_image_select/tests/src/Functional/WebformImageSelectElementTest.php
index 5f84628a17..d6346be14d 100644
--- a/web/modules/webform/modules/webform_image_select/tests/src/Functional/WebformImageSelectElementTest.php
+++ b/web/modules/webform/modules/webform_image_select/tests/src/Functional/WebformImageSelectElementTest.php
@@ -32,7 +32,7 @@ public function testImageSelect() {
     $this->assertRaw('<select data-limit="2" data-drupal-selector="edit-image-select-limit" data-images="{&quot;kitten_1&quot;:{&quot;text&quot;:&quot;Cute Kitten 1&quot;,&quot;src&quot;:&quot;http:\/\/placekitten.com\/220\/200&quot;},&quot;kitten_2&quot;:{&quot;text&quot;:&quot;Cute Kitten 2&quot;,&quot;src&quot;:&quot;http:\/\/placekitten.com\/180\/200&quot;},&quot;kitten_3&quot;:{&quot;text&quot;:&quot;Cute Kitten 3&quot;,&quot;src&quot;:&quot;http:\/\/placekitten.com\/130\/200&quot;},&quot;kitten_4&quot;:{&quot;text&quot;:&quot;Cute Kitten 4&quot;,&quot;src&quot;:&quot;http:\/\/placekitten.com\/270\/200&quot;}}" class="webform-image-select js-webform-image-select form-select" multiple="multiple" name="image_select_limit[]" id="edit-image-select-limit">');
 
     // Check rendering of image select with HTML markup and XSS test.
-    $this->assertRaw('<select data-drupal-selector="edit-image-select-html" data-show-label="data-show-label" data-images="{&quot;\u003C1\u003E&quot;:{&quot;text&quot;:&quot;Cute Kitten 1&quot;,&quot;src&quot;:&quot;http:\/\/placekitten.com\/220\/200&quot;},&quot;\u00222\u0022&quot;:{&quot;text&quot;:&quot;Cute \u003Cem\u003EKitten\u003C\/em\u003E 2&quot;,&quot;src&quot;:&quot;http:\/\/placekitten.com\/180\/200&quot;},&quot;\u00263&quot;:{&quot;text&quot;:&quot;Cute Kitten 3&quot;,&quot;src&quot;:&quot;http:\/\/placekitten.com\/130\/200&quot;},&quot;4&quot;:{&quot;text&quot;:&quot;Cute Kitten 4 alert(\u0022XSS\u0022);&quot;,&quot;src&quot;:&quot;http:\/\/placekitten.com\/270\/200&quot;}}" class="webform-image-select js-webform-image-select form-select" id="edit-image-select-html" name="image_select_html"><option value="" selected="selected">- None -</option><option value="&lt;1&gt;">');
+    $this->assertRaw('<select data-drupal-selector="edit-image-select-html" data-show-label="data-show-label" data-images="{&quot;\u003C1\u003E&quot;:{&quot;text&quot;:&quot;Cute \u003Cb style=\u0022color:red\u0022\u003EKitten\u003C\/b\u003E 1&quot;,&quot;src&quot;:&quot;http:\/\/placekitten.com\/220\/200&quot;},&quot;\u00222\u0022&quot;:{&quot;text&quot;:&quot;Cute \u003Cem style=\u0022color:blue\u0022\u003EKitten\u003C\/em\u003E 2&quot;,&quot;src&quot;:&quot;http:\/\/placekitten.com\/180\/200&quot;},&quot;\u00263&quot;:{&quot;text&quot;:&quot;Cute \u003Cu style=\u0022color:green\u0022\u003EKitten\u003C\/u\u003E 3&quot;,&quot;src&quot;:&quot;http:\/\/placekitten.com\/130\/200&quot;},&quot;4&quot;:{&quot;text&quot;:&quot;Cute Kitten 4 alert(\u0022XSS\u0022);&quot;,&quot;src&quot;:&quot;http:\/\/placekitten.com\/270\/200&quot;}}" class="webform-image-select js-webform-image-select form-select" id="edit-image-select-html" name="image_select_html"><option value="" selected="selected">- None -</option><option value="&lt;1&gt;">Cute Kitten 1</option><option value="&quot;2&quot;">Cute Kitten 2</option><option value="&amp;3">Cute Kitten 3</option><option value="4">Cute Kitten 4 alert(&quot;XSS&quot;);</option></select>');
 
     // Check rendering with filter.
     $this->assertRaw('<input class="webform-form-filter-text form-search" data-focus="false" data-item-singlular="animal" data-item-plural="animals" data-summary=".js-image-select-filter-custom-filter .webform-image-select-summary" data-no-results=".js-image-select-filter-custom-filter .webform-image-select-no-results" data-element=".js-image-select-filter-custom-filter .thumbnails" data-source=".thumbnail p" data-parent="li" data-selected=".selected" title="Enter a keyword to filter by." type="search" id="edit-image-select-filter-custom-filter" name="image_select_filter_custom_filter" size="30" maxlength="128" placeholder="Find an animal" />');
diff --git a/web/modules/webform/modules/webform_image_select/webform_image_select.info.yml b/web/modules/webform/modules/webform_image_select/webform_image_select.info.yml
index a3c6d33b27..d4a1e99881 100644
--- a/web/modules/webform/modules/webform_image_select/webform_image_select.info.yml
+++ b/web/modules/webform/modules/webform_image_select/webform_image_select.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_jqueryui_buttons/tests/modules/webform_jqueryui_buttons_test/config/install/webform.webform.test_element_buttons.yml b/web/modules/webform/modules/webform_jqueryui_buttons/tests/modules/webform_jqueryui_buttons_test/config/install/webform.webform.test_element_buttons.yml
index edd07e1750..1a1154cf77 100644
--- a/web/modules/webform/modules/webform_jqueryui_buttons/tests/modules/webform_jqueryui_buttons_test/config/install/webform.webform.test_element_buttons.yml
+++ b/web/modules/webform/modules/webform_jqueryui_buttons/tests/modules/webform_jqueryui_buttons_test/config/install/webform.webform.test_element_buttons.yml
@@ -47,7 +47,7 @@ elements: |
     '#other__option_label': Other
     '#other__placeholder': 'What is this other option'
     '#other__description': 'Other button description'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -161,6 +161,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -219,3 +220,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_jqueryui_buttons/tests/modules/webform_jqueryui_buttons_test/webform_jqueryui_buttons_test.info.yml b/web/modules/webform/modules/webform_jqueryui_buttons/tests/modules/webform_jqueryui_buttons_test/webform_jqueryui_buttons_test.info.yml
index 39feb12903..0736fa2684 100644
--- a/web/modules/webform/modules/webform_jqueryui_buttons/tests/modules/webform_jqueryui_buttons_test/webform_jqueryui_buttons_test.info.yml
+++ b/web/modules/webform/modules/webform_jqueryui_buttons/tests/modules/webform_jqueryui_buttons_test/webform_jqueryui_buttons_test.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform_jqueryui_buttons'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_jqueryui_buttons/webform_jqueryui_buttons.info.yml b/web/modules/webform/modules/webform_jqueryui_buttons/webform_jqueryui_buttons.info.yml
index 257b21ccf3..3dfdd83e75 100644
--- a/web/modules/webform/modules/webform_jqueryui_buttons/webform_jqueryui_buttons.info.yml
+++ b/web/modules/webform/modules/webform_jqueryui_buttons/webform_jqueryui_buttons.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_location_geocomplete/tests/modules/webform_location_geocomplete_test/config/install/webform.webform.test_element_loc_geocomplete.yml b/web/modules/webform/modules/webform_location_geocomplete/tests/modules/webform_location_geocomplete_test/config/install/webform.webform.test_element_loc_geocomplete.yml
index e19019c402..c449b00a93 100644
--- a/web/modules/webform/modules/webform_location_geocomplete/tests/modules/webform_location_geocomplete_test/config/install/webform.webform.test_element_loc_geocomplete.yml
+++ b/web/modules/webform/modules/webform_location_geocomplete/tests/modules/webform_location_geocomplete_test/config/install/webform.webform.test_element_loc_geocomplete.yml
@@ -94,7 +94,7 @@ elements: |
     '#title': 'Location with geolocation and hidden'
     '#geolocation': true
     '#hidden': true
-
+  
 css: ''
 javascript: ''
 settings:
@@ -208,6 +208,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -266,3 +267,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_location_geocomplete/tests/modules/webform_location_geocomplete_test/webform_location_geocomplete_test.info.yml b/web/modules/webform/modules/webform_location_geocomplete/tests/modules/webform_location_geocomplete_test/webform_location_geocomplete_test.info.yml
index 4ba1c61c60..964bd8fdd3 100644
--- a/web/modules/webform/modules/webform_location_geocomplete/tests/modules/webform_location_geocomplete_test/webform_location_geocomplete_test.info.yml
+++ b/web/modules/webform/modules/webform_location_geocomplete/tests/modules/webform_location_geocomplete_test/webform_location_geocomplete_test.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform_location_geocomplete'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_location_geocomplete/webform_location_geocomplete.info.yml b/web/modules/webform/modules/webform_location_geocomplete/webform_location_geocomplete.info.yml
index 767f11ca45..1416ac59b5 100644
--- a/web/modules/webform/modules/webform_location_geocomplete/webform_location_geocomplete.info.yml
+++ b/web/modules/webform/modules/webform_location_geocomplete/webform_location_geocomplete.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_node/src/Access/WebformNodeAccess.php b/web/modules/webform/modules/webform_node/src/Access/WebformNodeAccess.php
index 0bc7fecfc9..c4cede6a6e 100644
--- a/web/modules/webform/modules/webform_node/src/Access/WebformNodeAccess.php
+++ b/web/modules/webform/modules/webform_node/src/Access/WebformNodeAccess.php
@@ -196,25 +196,21 @@ protected static function checkAccess($operation, $entity_access, NodeInterface
     }
 
     // Check the node operation.
-    if ($operation && $node->access($operation, $account)) {
-      return AccessResult::allowed();
-    }
+    $result = $operation ? $node->access($operation, $account, TRUE) : AccessResult::neutral();
 
     // Check entity access.
     if ($entity_access) {
       // Check entity access for the webform.
-      if (strpos($entity_access, 'webform.') === 0
-        && $webform->access(str_replace('webform.', '', $entity_access), $account)) {
-        return AccessResult::allowed();
+      if (strpos($entity_access, 'webform.') === 0) {
+        $result = $result->orIf($webform->access(str_replace('webform.', '', $entity_access), $account, TRUE));
       }
       // Check entity access for the webform submission.
-      if (strpos($entity_access, 'webform_submission.') === 0
-        && $webform_submission->access(str_replace('webform_submission.', '', $entity_access), $account)) {
-        return AccessResult::allowed();
+      if (strpos($entity_access, 'webform_submission.') === 0) {
+        $result = $result->orIf($webform_submission->access(str_replace('webform_submission.', '', $entity_access), $account, TRUE));
       }
     }
 
-    return AccessResult::forbidden();
+    return $result;
   }
 
 }
diff --git a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/config/install/webform.webform.webform_node_test_multiple_a.yml b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/config/install/webform.webform.webform_node_test_multiple_a.yml
index e84446be01..8b4508d08b 100644
--- a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/config/install/webform.webform.webform_node_test_multiple_a.yml
+++ b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/config/install/webform.webform.webform_node_test_multiple_a.yml
@@ -132,6 +132,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -182,3 +183,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/config/install/webform.webform.webform_node_test_multiple_b.yml b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/config/install/webform.webform.webform_node_test_multiple_b.yml
index ad8a037a85..0c47366160 100644
--- a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/config/install/webform.webform.webform_node_test_multiple_b.yml
+++ b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/config/install/webform.webform.webform_node_test_multiple_b.yml
@@ -132,6 +132,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -182,3 +183,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/webform_node_test_multiple.info.yml b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/webform_node_test_multiple.info.yml
index 9f42d7953f..fd523eaa60 100644
--- a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/webform_node_test_multiple.info.yml
+++ b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/webform_node_test_multiple.info.yml
@@ -13,7 +13,7 @@ dependencies:
   - 'webform:webform'
   - 'webform:webform_node'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_translation/config/install/webform.webform.webform_node_test_translation.yml b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_translation/config/install/webform.webform.webform_node_test_translation.yml
index 55467eef68..4354fd16ac 100644
--- a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_translation/config/install/webform.webform.webform_node_test_translation.yml
+++ b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_translation/config/install/webform.webform.webform_node_test_translation.yml
@@ -133,6 +133,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -183,3 +184,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_translation/webform_node_test_translation.info.yml b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_translation/webform_node_test_translation.info.yml
index cbfe8f593c..50b411d56c 100644
--- a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_translation/webform_node_test_translation.info.yml
+++ b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_translation/webform_node_test_translation.info.yml
@@ -9,7 +9,7 @@ dependencies:
   - 'webform:webform_test_translation'
   - 'drupal:content_translation'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeTest.php b/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeTest.php
index 37cdd4d114..b49645b2f0 100644
--- a/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeTest.php
+++ b/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeTest.php
@@ -42,6 +42,10 @@ public function setUp() {
    * Tests webform node.
    */
   public function testNode() {
+    global $base_path;
+
+    /** @var \Drupal\webform\WebformInterface $webform */
+    $webform = Webform::load('contact');
     $node = $this->createWebformNode('contact');
 
     /** @var \Drupal\webform\WebformEntityReferenceManagerInterface $entity_reference_manager */
@@ -72,6 +76,27 @@ public function testNode() {
     $this->drupalGet('/node/' . $node->id());
     $this->assertFieldByName('name', 'John Smith');
 
+    /**************************************************************************/
+    // Webform closed.
+    /**************************************************************************/
+
+    $webform->setStatus(WebformInterface::STATUS_CLOSED);
+    $webform->save();
+
+    // Check page closed message
+    $this->drupalGet('/node/' . $node->id());
+    $this->assertRaw('Sorry… This form is closed to new submissions.');
+
+    $this->drupalLogin($this->rootUser);
+
+    // Check webform closed warning
+    $this->drupalGet('/node/' . $node->id() . '/edit');
+    $this->assertRaw('The <em class="placeholder">Contact</em> webform is <a href="' . $base_path . 'admin/structure/webform/manage/contact/settings/form">closed</a>. The below status will be ignored.');
+
+    $webform->setStatus(WebformInterface::STATUS_OPEN);
+    $webform->save();
+    $this->drupalLogout();
+
     /**************************************************************************/
     // Webform node open and closed.
     /**************************************************************************/
@@ -96,7 +121,7 @@ public function testNode() {
     $this->assertRaw('This is a custom inline confirmation message.');
 
     /**************************************************************************/
-    // Webform node scheduleD.
+    // Webform node scheduled.
     /**************************************************************************/
 
     // Check scheduled to open.
diff --git a/web/modules/webform/modules/webform_node/webform_node.info.yml b/web/modules/webform/modules/webform_node/webform_node.info.yml
index 8bbc186ebf..c40dd7e3a1 100644
--- a/web/modules/webform/modules/webform_node/webform_node.info.yml
+++ b/web/modules/webform/modules/webform_node/webform_node.info.yml
@@ -11,7 +11,7 @@ dependencies:
   - 'drupal:user'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_node/webform_node.module b/web/modules/webform/modules/webform_node/webform_node.module
index 7d392d3225..e7cd092ebf 100644
--- a/web/modules/webform/modules/webform_node/webform_node.module
+++ b/web/modules/webform/modules/webform_node/webform_node.module
@@ -62,7 +62,7 @@ function webform_node_node_access(NodeInterface $node, $operation, AccountInterf
       return AccessResult::allowed();
     }
 
-    return AccessResult::forbidden();
+    return AccessResult::neutral();
   }
 }
 
diff --git a/web/modules/webform/modules/webform_options_custom/config/install/webform.webform.example_options_custom.yml b/web/modules/webform/modules/webform_options_custom/config/install/webform.webform.example_options_custom.yml
index 8b627b82ed..2b5ce41791 100644
--- a/web/modules/webform/modules/webform_options_custom/config/install/webform.webform.example_options_custom.yml
+++ b/web/modules/webform/modules/webform_options_custom/config/install/webform.webform.example_options_custom.yml
@@ -141,6 +141,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -191,3 +192,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_entity_test/config/install/webform.webform.test_element_options_custom_ent.yml b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_entity_test/config/install/webform.webform.test_element_options_custom_ent.yml
index 77d7adae65..4785e0f89b 100644
--- a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_entity_test/config/install/webform.webform.test_element_options_custom_ent.yml
+++ b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_entity_test/config/install/webform.webform.test_element_options_custom_ent.yml
@@ -141,6 +141,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -219,3 +220,4 @@ handlers:
       option_unlimited_message: ' [Unlimited]'
       option_none_message: ' [@remaining remaining]'
       option_error_message: '@name: @label is unavailable.'
+variants: {  }
diff --git a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_entity_test/webform_options_custom_entity_test.info.yml b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_entity_test/webform_options_custom_entity_test.info.yml
index c5d799ddbd..99c93e4606 100644
--- a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_entity_test/webform_options_custom_entity_test.info.yml
+++ b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_entity_test/webform_options_custom_entity_test.info.yml
@@ -8,7 +8,7 @@ dependencies:
   - 'webform:webform_options_limit'
   - 'webform:webform_options_custom'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_html.yml b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_html.yml
index 479ce21dfe..4e1a279a59 100644
--- a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_html.yml
+++ b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_html.yml
@@ -162,6 +162,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -220,3 +221,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_imap.yml b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_imap.yml
index 750999e4f0..eeabcb767d 100644
--- a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_imap.yml
+++ b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_imap.yml
@@ -132,6 +132,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -190,3 +191,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_svg.yml b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_svg.yml
index 3b85c5accb..92f7e763c4 100644
--- a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_svg.yml
+++ b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_svg.yml
@@ -138,6 +138,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -196,3 +197,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_twig.yml b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_twig.yml
index 259e323b5c..62b486013a 100644
--- a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_twig.yml
+++ b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_twig.yml
@@ -136,6 +136,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -194,3 +195,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform_options_custom.webform_options_custom.test_ballroom.yml b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform_options_custom.webform_options_custom.test_ballroom.yml
index 75772cd69b..3817558c1e 100644
--- a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform_options_custom.webform_options_custom.test_ballroom.yml
+++ b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform_options_custom.webform_options_custom.test_ballroom.yml
@@ -3,8 +3,8 @@ status: true
 dependencies: {  }
 id: test_ballroom
 label: 'Test: Ballroom'
-description: 'A SVG image of a a ballroom'
-help: 'A SVG image of a a ballroom'
+description: 'A SVG image of a ballroom'
+help: 'A SVG image of a ballroom'
 category: Test
 type: url
 template: ''
diff --git a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/webform_options_custom_test.info.yml b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/webform_options_custom_test.info.yml
index 55cada576b..85d497109a 100644
--- a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/webform_options_custom_test.info.yml
+++ b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/webform_options_custom_test.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform_options_custom'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_options_custom/webform_options_custom.info.yml b/web/modules/webform/modules/webform_options_custom/webform_options_custom.info.yml
index bdaf2f9580..8c5183e714 100644
--- a/web/modules/webform/modules/webform_options_custom/webform_options_custom.info.yml
+++ b/web/modules/webform/modules/webform_options_custom/webform_options_custom.info.yml
@@ -7,7 +7,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_options_limit/config/schema/webform_options_limit.schema.yml b/web/modules/webform/modules/webform_options_limit/config/schema/webform_options_limit.schema.yml
index 39acc80e7d..7671955707 100644
--- a/web/modules/webform/modules/webform_options_limit/config/schema/webform_options_limit.schema.yml
+++ b/web/modules/webform/modules/webform_options_limit/config/schema/webform_options_limit.schema.yml
@@ -41,3 +41,6 @@ webform.handler.options_limit:
     option_error_message:
       type: label
       label: 'Option validation error message'
+    tableselect_header:
+      type: label
+      label: 'Table select header'
diff --git a/web/modules/webform/modules/webform_options_limit/src/Plugin/WebformHandler/OptionsLimitWebformHandler.php b/web/modules/webform/modules/webform_options_limit/src/Plugin/WebformHandler/OptionsLimitWebformHandler.php
index 89edd21b6f..4640630d71 100644
--- a/web/modules/webform/modules/webform_options_limit/src/Plugin/WebformHandler/OptionsLimitWebformHandler.php
+++ b/web/modules/webform/modules/webform_options_limit/src/Plugin/WebformHandler/OptionsLimitWebformHandler.php
@@ -16,6 +16,7 @@
 use Drupal\webform\Element\WebformMessage;
 use Drupal\webform\Plugin\WebformElement\BooleanBase;
 use Drupal\webform\Plugin\WebformElement\OptionsBase;
+use Drupal\webform\Plugin\WebformElement\TableSelect;
 use Drupal\webform\Plugin\WebformElementEntityOptionsInterface;
 use Drupal\webform\Plugin\WebformElementManagerInterface;
 use Drupal\webform\Plugin\WebformHandlerBase;
@@ -209,6 +210,7 @@ public function defaultConfiguration() {
       'option_unlimited_message' => '[Unlimited]',
       'option_none_message' => '[@remaining remaining]',
       'option_error_message' => '@name: @label is unavailable.',
+      'tableselect_header' => '',
     ];
   }
 
@@ -387,7 +389,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
         'visible' => [
           ':input[name="settings[limit_user]"]' => ['checked' => TRUE],
         ]
-      ]
+      ],
     ];
     // Option settings.
     $form['option_settings'] = [
@@ -461,6 +463,27 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
       '#default_value' => $this->configuration['option_error_message'],
       '#required' => TRUE,
     ];
+    if ($tableselect_elements = $this->getTableSelectElements()) {
+      $tableselect_states = [];
+      foreach ($tableselect_elements as $tableselect_element_key) {
+        if ($tableselect_states) {
+          $tableselect_states[] = 'or';
+        }
+        $tableselect_states[] = [':input[name="settings[element_key]"]' => ['value' => $tableselect_element_key]];
+      }
+      $form['option_settings']['tableselect_header'] = [
+        '#type' => 'textfield',
+        '#title' => $this->t('Table select description header'),
+        '#description' => $this->t("The label is displayed in the header for the table select's option limit column."),
+        '#default_value' => $this->configuration['tableselect_header'],
+        '#states' => [
+          'visible' => [
+            ':input[name="settings[option_message_display]"]' => ['value' => static::MESSAGE_DISPLAY_DESCRIPTION],
+            $tableselect_states,
+          ],
+        ],
+      ];
+    }
 
     // Placeholder help.
     $form['placeholder_help'] = [
@@ -529,6 +552,14 @@ public function alterElement(array &$element, FormStateInterface $form_state, ar
       $limits = $this->getOptionsLimits();
       $reached = $this->getOptionsReached($limits);
 
+      // Set table select description in header.
+      if ($this->isTableSelectElement()) {
+        $message_display = $this->configuration['option_message_display'];
+        if ($message_display === static::MESSAGE_DISPLAY_DESCRIPTION) {
+          $element['#header']['webform_options_limit'] = $this->configuration['tableselect_header'] ?: '';
+        }
+      }
+
       // Cleanup options element default value.
       $this->setOptionsElementDefaultValue($element, $limits, $reached, $operation);
 
@@ -632,7 +663,12 @@ protected function setOptionsElementDefaultValue(array &$element, array $limits,
     elseif (!empty($element['#default_value'])) {
       $default_value = $element['#default_value'];
       if ($has_multiple_values) {
-        $element['#default_value'] = array_values(array_diff($default_value, $reached));
+        if ($this->isTableSelectElement()) {
+          $element['#default_value'] = array_diff($default_value, $reached);
+        }
+        else {
+          $element['#default_value'] = array_values(array_diff($default_value, $reached));
+        }
       }
       else {
         if (isset($reached[$default_value])) {
@@ -679,14 +715,36 @@ protected function alterOptionsElement(array &$element, array $limits, array $re
   /**
    * Alter an options element's option labels recursively.
    *
-   * @param array $element
+   * @param array $options
    *   An options element with limits.
    * @param array $limits
    *   An options element's option limits.
    */
   protected function alterOptionsElementLabels(array &$options, array $limits) {
+    $message_display = $this->configuration['option_message_display'];
     foreach ($options as $option_value => $option_text) {
-      if (is_array($option_text)) {
+      if ($this->isTableSelectElement()) {
+        if (isset($limits[$option_value])) {
+          $label = $this->getOptionsLimitLabel(
+            $option_text[0]['value'],
+            $limits[$option_value]
+          );
+          $message_display = $this->configuration['option_message_display'];
+          $option =& $options[$option_value][0];
+          switch ($message_display) {
+            case static::MESSAGE_DISPLAY_DESCRIPTION:
+              list(
+                $option['value'],
+                $option['webform_options_limit']) = explode(' --', $label);
+              break;
+
+            case static::MESSAGE_DISPLAY_LABEL:
+              $option['value'] = $label;
+              break;
+          }
+        }
+      }
+      elseif (is_array($option_text)) {
         $this->alterOptionsElementLabels($option_text, $limits);
       }
       elseif (isset($limits[$option_value])) {
@@ -708,7 +766,13 @@ protected function alterOptionsElementLabels(array &$options, array $limits) {
    */
   protected function disableOptionsElement(array &$element, array $reached) {
     $webform_element = $this->getWebformElement();
-    if ($webform_element->hasProperty('options__properties')) {
+    if ($this->isTableSelectElement()) {
+      // Hide disabled table select checkbox or radio.
+      foreach ($reached as $reached_option) {
+        $element[$reached_option]['#access'] = FALSE;
+      }
+    }
+    elseif ($webform_element->hasProperty('options__properties')) {
       // Set element options disabled properties.
       foreach ($reached as $reached_option) {
         $element['#options__properties'][$reached_option] = [
@@ -848,7 +912,7 @@ protected function alterBooleanElement(array &$element, array $limit) {
           case static::MESSAGE_DISPLAY_LABEL:
             $t_args = [
               '@label' => $element['#title'],
-              '@message' => $message
+              '@message' => $message,
             ];
             $element['#title'] = $this->t('@label @message', $t_args);
             break;
@@ -1055,6 +1119,17 @@ protected function isBooleanElement() {
     return ($webform_element instanceof BooleanBase);
   }
 
+  /**
+   * Determine if table select  element.
+   *
+   * @return string
+   *   TRUE if table select element.
+   */
+  protected function isTableSelectElement() {
+    $webform_element = $this->getWebformElement();
+    return ($webform_element instanceof TableSelect);
+  }
+
   /**
    * Get selected webform element label.
    *
@@ -1080,8 +1155,7 @@ protected function getElements() {
     $options = [];
     foreach ($elements as $element) {
       $webform_element = $this->elementManager->getElementInstance($element);
-      $is_options_element = ($webform_element->hasProperty('options')
-        && strpos($webform_element->getPluginLabel(), 'tableselect') === FALSE);
+      $is_options_element = $webform_element->hasProperty('options');
       $is_entity_options_element = ($webform_element instanceof WebformElementEntityOptionsInterface);
       $is_boolean_element = ($webform_element instanceof BooleanBase);
       if ($is_options_element || $is_entity_options_element || $is_boolean_element) {
@@ -1107,6 +1181,27 @@ protected function getElements() {
     return $options;
   }
 
+  /**
+   * Get table select elements.
+   *
+   * @return array
+   *   An array containing table select elements.
+   */
+  protected function getTableSelectElements() {
+    $webform = $this->getWebform();
+    $elements = $webform->getElementsInitializedAndFlattened();
+
+    $tableselect_elements = [];
+    foreach ($elements as $element_key => $element) {
+      $webform_element = $this->elementManager->getElementInstance($element);
+      if ($webform_element instanceof TableSelect) {
+        $tableselect_elements[$element_key] = $element_key;
+      }
+    }
+
+    return $tableselect_elements;
+  }
+
   /**
    * Get selected element's options.
    *
@@ -1189,7 +1284,7 @@ protected function getBooleanLimits() {
    * @param int $limit
    *   The limit.
    * @param int $total
-   *   The total
+   *   The total.
    *
    * @return array
    *   The limit information including label, limit, total,
@@ -1269,7 +1364,7 @@ protected function getOptionsTotals(array $values = []) {
     return $query->execute()->fetchAllKeyed();
   }
 
- /**
+  /**
    * Get boolean submission total for the current webform and source entity.
    *
    * @return int
diff --git a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_boolean_limit.yml b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_boolean_limit.yml
index 4cb3b83da6..3fb731c774 100644
--- a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_boolean_limit.yml
+++ b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_boolean_limit.yml
@@ -29,6 +29,7 @@ elements: |
     '#type': checkbox
     '#title': boolean_limit_remove
     '#default_value': true
+  
 css: ''
 javascript: ''
 settings:
@@ -142,6 +143,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -255,3 +257,4 @@ handlers:
       option_none_message: '[@remaining remaining]'
       option_unlimited_message: '[Unlimited]'
       option_error_message: '@name: @label is unavailable.'
+variants: {  }
diff --git a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit.yml b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit.yml
index cbb671ac28..fdc48f5b93 100644
--- a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit.yml
+++ b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit.yml
@@ -91,7 +91,26 @@ elements: |
       - R
       - S
       - T
-
+  options_limit_tableselect_multiple:
+    '#type': tableselect
+    '#title': options_limit_tableselect_multiple
+    '#options':
+      U: U
+      V: V
+      W: W
+    '#default_value':
+      - U
+      - V
+      - W
+  options_limit_tableselect_single:
+    '#type': tableselect
+    '#title': options_limit_tableselect_single
+    '#multiple': false
+    '#options':
+      X: X
+      Y: Y
+      Z: Z
+    '#default_value': X
 css: ''
 javascript: ''
 settings:
@@ -205,6 +224,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -278,6 +298,7 @@ handlers:
       option_none_message: '[@remaining remaining]'
       option_unlimited_message: '[Unlimited]'
       option_error_message: '@name: @label is unavailable.'
+      tableselect_header: ''
   options_limit_messages:
     id: options_limit
     label: options_limit_messages
@@ -300,6 +321,7 @@ handlers:
       option_none_message: 'No options remaining / @limit limit / @total total'
       option_unlimited_message: 'Unlimited / @total total'
       option_error_message: '@name: @label is unavailable.'
+      tableselect_header: ''
   options_limit_select_disable:
     id: options_limit
     label: options_limit_select_disable
@@ -322,6 +344,7 @@ handlers:
       option_none_message: '[@remaining remaining]'
       option_unlimited_message: '[Unlimited]'
       option_error_message: '@name: @label is unavailable.'
+      tableselect_header: ''
   options_limit_select_remove:
     id: options_limit
     label: options_limit_select_remove
@@ -344,6 +367,7 @@ handlers:
       option_none_message: '[@remaining remaining]'
       option_unlimited_message: '[Unlimited]'
       option_error_message: '@name: @label is unavailable.'
+      tableselect_header: ''
   options_limit_select_none:
     id: options_limit
     label: options_limit_select_none
@@ -366,6 +390,7 @@ handlers:
       option_none_message: '[@remaining remaining]'
       option_unlimited_message: '[Unlimited]'
       option_error_message: '@name: @label is unavailable.'
+      tableselect_header: ''
   options_limit_select_other:
     id: options_limit
     label: options_limit_select_other
@@ -388,3 +413,51 @@ handlers:
       option_none_message: '[@remaining remaining]'
       option_unlimited_message: '[Unlimited]'
       option_error_message: '@name: @label is unavailable.'
+      tableselect_header: ''
+  options_limit_tableselect_multiple:
+    id: options_limit
+    label: options_limit_tableselect_multiple
+    handler_id: options_limit_tableselect_multiple
+    status: true
+    conditions: {  }
+    weight: 0
+    settings:
+      element_key: options_limit_tableselect_multiple
+      limits:
+        U: 1
+        V: 2
+      limit_reached_message: '@name is not available.'
+      limit_source_entity: true
+      limit_user: false
+      option_none_action: disable
+      option_message_display: label
+      option_multiple_message: '[@remaining remaining]'
+      option_single_message: '[@remaining remaining]'
+      option_none_message: '[@remaining remaining]'
+      option_unlimited_message: '[Unlimited]'
+      option_error_message: '@name: @label is unavailable.'
+      tableselect_header: ''
+  options_limit_tableselect_single:
+    id: options_limit
+    label: options_limit_tableselect_single
+    handler_id: options_limit_tableselect_single
+    status: true
+    conditions: {  }
+    weight: 0
+    settings:
+      element_key: options_limit_tableselect_single
+      limits:
+        X: 1
+        Y: 2
+      limit_reached_message: '@name is not available.'
+      limit_source_entity: true
+      limit_user: false
+      option_none_action: disable
+      option_message_display: description
+      option_multiple_message: '[@remaining remaining]'
+      option_single_message: '[@remaining remaining]'
+      option_none_message: '[@remaining remaining]'
+      option_unlimited_message: '[Unlimited]'
+      option_error_message: '@name: @label is unavailable.'
+      tableselect_header: 'Limits'
+variants: {  }
diff --git a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit_ent.yml b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit_ent.yml
index 4b7375d9c0..efb23c681e 100644
--- a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit_ent.yml
+++ b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit_ent.yml
@@ -140,6 +140,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -211,3 +212,5 @@ handlers:
       option_unlimited_message: '[Unlimited]'
       option_none_message: '[@remaining remaining]'
       option_error_message: '@name: @label is unavailable.'
+      tableselect_header: ''
+variants: {  }
diff --git a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit_user.yml b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit_user.yml
index fced4e6d17..b7b9ad61c7 100644
--- a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit_user.yml
+++ b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit_user.yml
@@ -142,6 +142,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -215,3 +216,5 @@ handlers:
       option_none_message: '[@remaining remaining]'
       option_unlimited_message: '[Unlimited]'
       option_error_message: '@name: @label is unavailable.'
+      tableselect_header: ''
+variants: {  }
diff --git a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/webform_options_limit_test.info.yml b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/webform_options_limit_test.info.yml
index 07e1c579a7..83a06626e2 100644
--- a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/webform_options_limit_test.info.yml
+++ b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/webform_options_limit_test.info.yml
@@ -7,7 +7,7 @@ dependencies:
   - 'webform:webform'
   - 'webform:webform_options_limit'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitTest.php b/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitTest.php
index 7a7a056d74..98dce40588 100644
--- a/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitTest.php
+++ b/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitTest.php
@@ -46,6 +46,18 @@ public function testOptionsLimit() {
     // Check that option O is available.
     $this->assertRaw('<option value="O" selected="selected">O [1 remaining]</option>');
 
+    // Check that table select multiple is available.
+    $this->assertFieldById('edit-options-limit-tableselect-multiple-u', 'U');
+    $this->assertRaw('<input class="tableselect form-checkbox" data-drupal-selector="edit-options-limit-tableselect-multiple-u" type="checkbox" id="edit-options-limit-tableselect-multiple-u" name="options_limit_tableselect_multiple[U]" value="U" checked="checked" />');
+    $this->assertRaw('<td>U [1 remaining]</td>');
+
+    // Check that table select single is available.
+    $this->assertFieldById('edit-options-limit-tableselect-single-x', 'X');
+    $this->assertRaw('<input class="tableselect form-radio" data-drupal-selector="edit-options-limit-tableselect-single-x" type="radio" id="edit-options-limit-tableselect-single-x" name="options_limit_tableselect_single" value="X" checked="checked" />');
+    $this->assertPattern('#<th>options_limit_tableselect_single</th>\s+<th>Limits</th>#');
+    $this->assertRaw('<td>X</td>');
+    $this->assertRaw('<td> [1 remaining]</td>');
+
     // Post first submission.
     $sid_1 = $this->postSubmission($webform);
 
@@ -67,6 +79,15 @@ public function testOptionsLimit() {
     // Check that option O was not changed but is not selected.
     $this->assertRaw('<option value="O">O [0 remaining]</option>');
 
+    // Check that table select multiple is NOT available.
+    $this->assertNoFieldById('edit-options-limit-tableselect-multiple-u', 'U');
+    $this->assertRaw('<td>U [0 remaining]</td>');
+
+    // Check that table select single is available.
+    $this->assertNoFieldById('edit-options-limit-tableselect-multiple-x', 'X');
+    $this->assertRaw('<td>X</td>');
+    $this->assertRaw('<td> [0 remaining]</td>');
+
     // Check that option O being selected triggers validation error.
     $this->postSubmission($webform, ['options_limit_select_none[]' => 'O']);
     $this->assertRaw('options_limit_select_none: O is unavailable.');
diff --git a/web/modules/webform/modules/webform_options_limit/webform_options_limit.info.yml b/web/modules/webform/modules/webform_options_limit/webform_options_limit.info.yml
index d8a47e14c9..d409d56e46 100644
--- a/web/modules/webform/modules/webform_options_limit/webform_options_limit.info.yml
+++ b/web/modules/webform/modules/webform_options_limit/webform_options_limit.info.yml
@@ -7,7 +7,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_options_limit/webform_options_limit.install b/web/modules/webform/modules/webform_options_limit/webform_options_limit.install
index 1db49f54c0..a1075870ea 100644
--- a/web/modules/webform/modules/webform_options_limit/webform_options_limit.install
+++ b/web/modules/webform/modules/webform_options_limit/webform_options_limit.install
@@ -14,3 +14,10 @@
 function webform_options_limit_update_8001() {
   _webform_update_webform_handler_settings();
 }
+
+/**
+ * Issue #3124729: Option Limit broken for Tableselect.
+ */
+function webform_options_limit_update_8002() {
+  _webform_update_webform_handler_settings();
+}
diff --git a/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test/config/install/webform.webform.test_handler_scheduled_email.yml b/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test/config/install/webform.webform.test_handler_scheduled_email.yml
index e8b2285f65..cda99a4449 100644
--- a/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test/config/install/webform.webform.test_handler_scheduled_email.yml
+++ b/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test/config/install/webform.webform.test_handler_scheduled_email.yml
@@ -39,7 +39,7 @@ elements: |
       visible:
         ':input[name="send"]':
           value: other
-
+  
 css: ''
 javascript: ''
 settings:
@@ -153,6 +153,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -465,3 +466,4 @@ handlers:
       unschedule: true
       ignore_past: false
       test_send: false
+variants: {  }
diff --git a/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test/webform_scheduled_email_test.info.yml b/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test/webform_scheduled_email_test.info.yml
index c0066adb8a..afe859a8a3 100644
--- a/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test/webform_scheduled_email_test.info.yml
+++ b/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test/webform_scheduled_email_test.info.yml
@@ -7,7 +7,7 @@ dependencies:
   - 'webform:webform'
   - 'webform:webform_scheduled_email'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test_translation/config/install/webform.webform.test_handler_scheduled_translate.yml b/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test_translation/config/install/webform.webform.test_handler_scheduled_translate.yml
index b945e04bda..c966044801 100644
--- a/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test_translation/config/install/webform.webform.test_handler_scheduled_translate.yml
+++ b/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test_translation/config/install/webform.webform.test_handler_scheduled_translate.yml
@@ -20,7 +20,7 @@ elements: |
   value:
     '#type': textfield
     '#title': value
-
+  
 css: ''
 javascript: ''
 settings:
@@ -134,6 +134,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -225,3 +226,4 @@ handlers:
       unschedule: false
       ignore_past: false
       test_send: false
+variants: {  }
diff --git a/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test_translation/webform_scheduled_email_test_translation.info.yml b/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test_translation/webform_scheduled_email_test_translation.info.yml
index 6111730cfa..47c7499524 100644
--- a/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test_translation/webform_scheduled_email_test_translation.info.yml
+++ b/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test_translation/webform_scheduled_email_test_translation.info.yml
@@ -10,7 +10,7 @@ dependencies:
   - 'webform:webform'
   - 'webform:webform_scheduled_email'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_scheduled_email/webform_scheduled_email.info.yml b/web/modules/webform/modules/webform_scheduled_email/webform_scheduled_email.info.yml
index 685ba943e1..9cfa4f18b4 100644
--- a/web/modules/webform/modules/webform_scheduled_email/webform_scheduled_email.info.yml
+++ b/web/modules/webform/modules/webform_scheduled_email/webform_scheduled_email.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_shortcuts/webform_shortcuts.info.yml b/web/modules/webform/modules/webform_shortcuts/webform_shortcuts.info.yml
index 3d2b863c5b..8fe54de993 100644
--- a/web/modules/webform/modules/webform_shortcuts/webform_shortcuts.info.yml
+++ b/web/modules/webform/modules/webform_shortcuts/webform_shortcuts.info.yml
@@ -7,7 +7,7 @@ dependencies:
   - 'webform:webform'
   - 'webform:webform_ui'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_shortcuts/webform_shortcuts.libraries.yml b/web/modules/webform/modules/webform_shortcuts/webform_shortcuts.libraries.yml
index 2af2ef049c..5d1864dd28 100644
--- a/web/modules/webform/modules/webform_shortcuts/webform_shortcuts.libraries.yml
+++ b/web/modules/webform/modules/webform_shortcuts/webform_shortcuts.libraries.yml
@@ -16,7 +16,7 @@ libraries.jquery.hotkeys:
     url: https://github.com/rvera/image-picker/blob/master/LICENSE
     gpl-compatible: true
   cdn:
-    /libraries/jquery.hotkeys/: https://cdn.rawgit.com/jeresig/jquery.hotkeys/0.2.0/
+    /libraries/jquery.hotkeys/: https://cdn.jsdelivr.net/gh/jeresig/jquery.hotkeys@0.2.0/
   js:
     /libraries/jquery.hotkeys/jquery.hotkeys.js: {}
   dependencies:
diff --git a/web/modules/webform/modules/webform_submission_export_import/src/WebformSubmissionExportImportImporter.php b/web/modules/webform/modules/webform_submission_export_import/src/WebformSubmissionExportImportImporter.php
index acc1df8984..e434fd2cbb 100644
--- a/web/modules/webform/modules/webform_submission_export_import/src/WebformSubmissionExportImportImporter.php
+++ b/web/modules/webform/modules/webform_submission_export_import/src/WebformSubmissionExportImportImporter.php
@@ -636,7 +636,7 @@ protected function importPrepareRecord(array &$record, WebformSubmissionInterfac
         $record[$element_key][$composite_key] = $value;
       }
       elseif ($element_plugin instanceof WebformCompositeBase) {
-        // Get the the composite element element and make sure it exists.
+        // Get the composite element and make sure it exists.
         $composite_elements = $element_plugin->getCompositeElements();
         if (!isset($composite_elements[$composite_key])) {
           continue;
diff --git a/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/config/install/webform.webform.test_submission_export_import.yml b/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/config/install/webform.webform.test_submission_export_import.yml
index 3ef38ff9f8..b56564c521 100644
--- a/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/config/install/webform.webform.test_submission_export_import.yml
+++ b/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/config/install/webform.webform.test_submission_export_import.yml
@@ -189,6 +189,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -239,3 +240,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/webform_submission_export_import_test.info.yml b/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/webform_submission_export_import_test.info.yml
index 0adee24171..c82d4c7c1e 100644
--- a/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/webform_submission_export_import_test.info.yml
+++ b/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/webform_submission_export_import_test.info.yml
@@ -7,7 +7,7 @@ dependencies:
   - 'webform:webform_submission_export_import'
   - 'webform:webform_image_select'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_submission_export_import/webform_submission_export_import.info.yml b/web/modules/webform/modules/webform_submission_export_import/webform_submission_export_import.info.yml
index 50d6beef29..8f4f9312cc 100644
--- a/web/modules/webform/modules/webform_submission_export_import/webform_submission_export_import.info.yml
+++ b/web/modules/webform/modules/webform_submission_export_import/webform_submission_export_import.info.yml
@@ -7,7 +7,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_submission_log/webform_submission_log.info.yml b/web/modules/webform/modules/webform_submission_log/webform_submission_log.info.yml
index daa1537537..cbe7452f1f 100644
--- a/web/modules/webform/modules/webform_submission_log/webform_submission_log.info.yml
+++ b/web/modules/webform/modules/webform_submission_log/webform_submission_log.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_contact.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_contact.yml
index 4c47449aac..84bf76431b 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_contact.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_contact.yml
@@ -35,7 +35,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': 'Send message'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -149,6 +149,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -271,3 +272,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_employee_evaluation.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_employee_evaluation.yml
index 72b4eb8952..96f2071d8f 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_employee_evaluation.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_employee_evaluation.yml
@@ -196,6 +196,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -246,3 +247,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_feedback.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_feedback.yml
index 3152858295..8fad7b6e96 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_feedback.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_feedback.yml
@@ -40,7 +40,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': 'Submit feedback'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -154,6 +154,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -286,3 +287,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_issue.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_issue.yml
index 35d8f7d7c4..34b084db8e 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_issue.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_issue.yml
@@ -237,6 +237,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -287,3 +288,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_job_application.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_job_application.yml
index 6cb42b3224..d0f855d044 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_job_application.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_job_application.yml
@@ -83,7 +83,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': Apply
-
+  
 css: ''
 javascript: ''
 settings:
@@ -197,6 +197,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -283,3 +284,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_job_seeker_profile.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_job_seeker_profile.yml
index 7448e97fc4..f414071d7d 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_job_seeker_profile.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_job_seeker_profile.yml
@@ -23,7 +23,7 @@ elements: |
       <li>Providing more information gives a better picture to employers</li>
       <li>Salary requirements, location preferences and skill level are all important factors in the hiring decision</li>
       </ul>
-
+  
   information:
     '#title': 'Job Seeker Information'
     '#type': webform_section
@@ -83,7 +83,7 @@ elements: |
       '#type': url
       '#title': Website
       '#description': 'Enter your existing profile/resume/portfolio link.'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -197,6 +197,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -283,3 +284,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_medical_appointment.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_medical_appointment.yml
index 5e7cb55a2b..2f7d7953f7 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_medical_appointment.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_medical_appointment.yml
@@ -205,7 +205,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': 'Send Request'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -319,6 +319,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -405,3 +406,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_registration.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_registration.yml
index 7eee39962f..da68524bc4 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_registration.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_registration.yml
@@ -52,7 +52,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': Register
-
+  
 css: ''
 javascript: ''
 settings:
@@ -166,6 +166,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -252,3 +253,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_session_evaluation.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_session_evaluation.yml
index 61f60393fb..f66b9adfc6 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_session_evaluation.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_session_evaluation.yml
@@ -44,7 +44,7 @@ elements: |
     '#type': textarea
     '#title': Comments
     '#description': 'What did you like most? What would you change? Advice for the speaker to make this session better?'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -158,6 +158,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -244,3 +245,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_subscribe.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_subscribe.yml
index 3f4ae8b8e8..329e0c09fc 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_subscribe.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_subscribe.yml
@@ -31,7 +31,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': Subscribe
-
+  
 css: ''
 javascript: ''
 settings:
@@ -145,6 +145,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -231,3 +232,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_user_profile.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_user_profile.yml
index a32620894d..3da2438bfe 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_user_profile.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_user_profile.yml
@@ -125,7 +125,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': Register
-
+  
 css: ''
 javascript: ''
 settings:
@@ -239,6 +239,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -325,3 +326,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/modules/webform_templates/webform_templates.info.yml b/web/modules/webform/modules/webform_templates/webform_templates.info.yml
index 5bdc08195a..ebd20de9eb 100644
--- a/web/modules/webform/modules/webform_templates/webform_templates.info.yml
+++ b/web/modules/webform/modules/webform_templates/webform_templates.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_toggles/tests/modules/webform_toggles_test/config/install/webform.webform.test_element_toggles.yml b/web/modules/webform/modules/webform_toggles/tests/modules/webform_toggles_test/config/install/webform.webform.test_element_toggles.yml
index 8ed6e6ceed..b565344e17 100644
--- a/web/modules/webform/modules/webform_toggles/tests/modules/webform_toggles_test/config/install/webform.webform.test_element_toggles.yml
+++ b/web/modules/webform/modules/webform_toggles/tests/modules/webform_toggles_test/config/install/webform.webform.test_element_toggles.yml
@@ -49,7 +49,7 @@ elements: |
         one: One
         two: Two
         three: Three
-
+  
 css: ''
 javascript: ''
 settings:
@@ -163,6 +163,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -221,3 +222,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_toggles/tests/modules/webform_toggles_test/webform_toggles_test.info.yml b/web/modules/webform/modules/webform_toggles/tests/modules/webform_toggles_test/webform_toggles_test.info.yml
index 650462bcce..35814f2ca5 100644
--- a/web/modules/webform/modules/webform_toggles/tests/modules/webform_toggles_test/webform_toggles_test.info.yml
+++ b/web/modules/webform/modules/webform_toggles/tests/modules/webform_toggles_test/webform_toggles_test.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform_toggles'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_toggles/webform_toggles.info.yml b/web/modules/webform/modules/webform_toggles/webform_toggles.info.yml
index b8b515a1b1..4aa7793c9b 100644
--- a/web/modules/webform/modules/webform_toggles/webform_toggles.info.yml
+++ b/web/modules/webform/modules/webform_toggles/webform_toggles.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/modules/webform_ui/css/webform_ui.module.css b/web/modules/webform/modules/webform_ui/css/webform_ui.module.css
index cff99c1411..362aa55923 100644
--- a/web/modules/webform/modules/webform_ui/css/webform_ui.module.css
+++ b/web/modules/webform/modules/webform_ui/css/webform_ui.module.css
@@ -111,12 +111,37 @@ thead th .dropbutton {
   .js-off-canvas-dialog-open .webform-ui-elements-table td {
     display: none;
   }
+
   .js-off-canvas-dialog-open .webform-ui-elements-table th:first-child,
+  .js-off-canvas-dialog-open .webform-ui-elements-table th:nth-child(2),
   .js-off-canvas-dialog-open .webform-ui-elements-table th:last-child,
   .js-off-canvas-dialog-open .webform-ui-elements-table td:first-child,
+  .js-off-canvas-dialog-open .webform-ui-elements-table td:nth-child(2),
   .js-off-canvas-dialog-open .webform-ui-elements-table td:last-child {
     display: table-cell;
   }
+
+  .js-off-canvas-dialog-open .webform-ui-elements-table th:nth-child(2) span,
+  .js-off-canvas-dialog-open .webform-ui-elements-table td:nth-child(2) span {
+    position: absolute !important;
+    overflow: hidden;
+    clip: rect(1px, 1px, 1px, 1px);
+    width: 1px;
+    height: 1px;
+    word-wrap: normal;
+  }
+}
+
+@media screen and (max-width: 600px) {
+  .webform-ui-elements-table th:nth-child(2) span,
+  .webform-ui-elements-table td:nth-child(2) span {
+    position: absolute !important;
+    overflow: hidden;
+    clip: rect(1px, 1px, 1px, 1px);
+    width: 1px;
+    height: 1px;
+    word-wrap: normal;
+  }
 }
 
 /**
diff --git a/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementFormBase.php b/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementFormBase.php
index 9aeda69300..98a71c5f06 100644
--- a/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementFormBase.php
+++ b/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementFormBase.php
@@ -10,6 +10,9 @@
 use Drupal\Core\Form\SubformState;
 use Drupal\Core\Render\RendererInterface;
 use Drupal\Core\Url;
+use Drupal\webform\Element\WebformMessage;
+use Drupal\webform\Plugin\WebformElement\WebformTable;
+use Drupal\webform\Plugin\WebformElement\WebformTableRow;
 use Drupal\webform\Plugin\WebformElementVariantInterface;
 use Drupal\webform\Utility\WebformDialogHelper;
 use Drupal\webform\Form\WebformDialogFormTrait;
@@ -292,7 +295,7 @@ public function buildForm(array $form, FormStateInterface $form_state, WebformIn
       '#parents' => ['key'],
       '#disabled' => ($key) ? TRUE : FALSE,
       '#default_value' => $key ?: $this->getDefaultKey(),
-      '#weight' => -98,
+      '#weight' => -97,
     ];
 
     // Remove the key's help text (aka description) once it has been set.
@@ -305,6 +308,20 @@ public function buildForm(array $form, FormStateInterface $form_state, WebformIn
       $form['properties']['element']['title']['#id'] = 'title';
     }
 
+    // Prefix table row child elements with the table row key.
+    if ($this->isNew()
+      && $parent_prefix = $this->getParentKeyPrefix($parent_key)) {
+      $form['properties']['element']['key']['#field_prefix'] = $parent_prefix . '_';
+      $form['properties']['element']['table_message'] = [
+        '#type' => 'webform_message',
+        '#message_message' => $this->t("Element keys are automatically prefixed with parent row's key."),
+        '#message_type' => 'warning',
+        '#message_close' => TRUE,
+        '#message_storage' => WebformMessage::STORAGE_SESSION,
+        '#weight' => -98,
+      ];
+    }
+
     // Set flex.
     // Hide #flex property if parent element is not a 'webform_flexbox'.
     if (isset($form['properties']['flex']) && !$this->isParentElementFlexbox($key, $parent_key)) {
@@ -321,7 +338,10 @@ public function buildForm(array $form, FormStateInterface $form_state, WebformIn
       '#button_type' => 'primary',
       '#_validate_form' => TRUE,
     ];
-    if ($this->operation === 'create' && $this->isAjax()) {
+    if ($this->operation === 'create'
+      && $this->isAjax()
+      && !$element_plugin instanceof WebformTable
+      && !$element_plugin instanceof WebformTableRow) {
       $form['actions']['save_add_element'] = [
         '#type' => 'submit',
         '#value' => $this->t('Save + Add element'),
@@ -373,6 +393,13 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
     $parent_key = $form_state->getValue('parent_key');
     $key = $form_state->getValue('key');
 
+    // Prefix table row child elements with the table row key.
+    if ($this->isNew()
+      && $parent_prefix = $this->getParentKeyPrefix($parent_key)) {
+      $key = $parent_prefix . '_' . $key;
+      $form_state->setValue('key', $key);
+    }
+
     // Update key for new and duplicated elements.
     $this->key = $key;
 
@@ -491,7 +518,7 @@ public function getParentKey() {
    * {@inheritdoc}
    */
   public function getWebformElementPlugin() {
-    return $this->elementManager->getElementInstance($this->element);
+    return $this->elementManager->getElementInstance($this->element, $this->getWebform());
   }
 
   /**
@@ -522,6 +549,54 @@ protected function isParentElementFlexbox($key = NULL, $parent_key = NULL) {
     return FALSE;
   }
 
+  /**
+   * Determine if parent key prefixing is enabled.
+   *
+   * @param string|null $parent_key
+   *   The element's parent key.
+   *
+   * @return bool
+   *   TRUE if parent key prefixing is enabled.
+   */
+  protected function isParentKeyPrefixEnabled($parent_key) {
+    while ($parent_key) {
+      $parent_element = $this->getWebform()->getElement($parent_key);
+      if ($parent_element['#type'] === 'webform_table') {
+        return (!isset($parent_element['#prefix_children']) || $parent_element['#prefix_children'] === TRUE);
+      }
+      $parent_key = $parent_element['#webform_parent_key'];
+    }
+    return FALSE;
+  }
+
+  /**
+   * Get the parent key prefix.
+   *
+   * Parent key prefix only applies to elements withing a
+   * 'webform_table_row'.
+   *
+   * @param string|null $parent_key
+   *   The element's parent key.
+   *
+   * @return string|null
+   *   The parent key prefix or NULL is no parent key prefix is applicable.
+   */
+  protected function getParentKeyPrefix($parent_key) {
+    if (!$this->isParentKeyPrefixEnabled($parent_key)) {
+      return NULL;
+    }
+
+    while ($parent_key) {
+      $parent_element = $this->getWebform()->getElement($parent_key);
+      if (strpos($parent_key, '01') !== FALSE
+        && $parent_element['#type'] === 'webform_table_row') {
+        return $parent_element['#webform_key'];
+      }
+      $parent_key = $parent_element['#webform_parent_key'];
+    }
+    return NULL;
+  }
+
   /****************************************************************************/
   // Element key handling.
   /****************************************************************************/
@@ -557,6 +632,11 @@ public function getDefaultKey() {
 
     $base_key = $element_plugin->getDefaultKey();
     $elements = $this->getWebform()->getElementsDecodedAndFlattened();
+
+    if (preg_match('/(^|_)(\d+$)($|_)/', $base_key) && !isset($elements[$base_key])) {
+      return $base_key;
+    }
+
     $increment = NULL;
     foreach ($elements as $element_key => $element) {
       if (strpos($element_key, $base_key) === 0) {
diff --git a/web/modules/webform/modules/webform_ui/src/WebformUiEntityElementsForm.php b/web/modules/webform/modules/webform_ui/src/WebformUiEntityElementsForm.php
index ecf761bc9c..f60d8998d8 100644
--- a/web/modules/webform/modules/webform_ui/src/WebformUiEntityElementsForm.php
+++ b/web/modules/webform/modules/webform_ui/src/WebformUiEntityElementsForm.php
@@ -15,6 +15,7 @@
 use Drupal\webform\Element\WebformElementStates;
 use Drupal\webform\Form\WebformEntityAjaxFormTrait;
 use Drupal\webform\Plugin\WebformElement\WebformElement;
+use Drupal\webform\Plugin\WebformElement\WebformTable;
 use Drupal\webform\Utility\WebformDialogHelper;
 use Drupal\webform\Plugin\WebformElementManagerInterface;
 use Drupal\webform\WebformEntityElementsValidatorInterface;
@@ -377,7 +378,7 @@ protected function getTableHeader() {
     if ($webform->hasContainer()) {
       $header['add'] = [
         'data' => '',
-        'class' => [RESPONSIVE_PRIORITY_MEDIUM, 'webform-ui-element-operations'],
+        'class' => ['webform-ui-element-operations'],
       ];
     }
     $header['key'] = [
@@ -531,12 +532,23 @@ protected function getElementRow(array $element, $delta, array $parent_options)
           'webform' => $webform->id(),
         ];
         $route_options = ['query' => ['parent' => $key]];
-        $row['add'] = [
-          '#type' => 'link',
-          '#title' => $this->t('Add element'),
-          '#url' => new Url('entity.webform_ui.element', $route_parameters, $route_options),
-          '#attributes' => WebformDialogHelper::getModalDialogAttributes(WebformDialogHelper::DIALOG_NORMAL, ['button', 'button-action', 'button--primary', 'button--small']),
-        ];
+        if ($webform_element instanceof WebformTable) {
+          $route_parameters['type'] = 'webform_table_row';
+          $row['add'] = [
+            '#type' => 'link',
+            '#title' => $this->t('Add <span>row</span>'),
+            '#url' => new Url('entity.webform_ui.element.add_form', $route_parameters, $route_options),
+            '#attributes' => WebformDialogHelper::getOffCanvasDialogAttributes(WebformDialogHelper::DIALOG_NORMAL, ['button', 'button-action', 'button--primary', 'button--small']),
+          ];
+        }
+        else {
+          $row['add'] = [
+            '#type' => 'link',
+            '#title' => $this->t('Add <span>element</span>'),
+            '#url' => new Url('entity.webform_ui.element', $route_parameters, $route_options),
+            '#attributes' => WebformDialogHelper::getModalDialogAttributes(WebformDialogHelper::DIALOG_NORMAL, ['button', 'button-action', 'button--primary', 'button--small']),
+          ];
+        }
       }
       else {
         $row['add'] = ['#markup' => ''];
@@ -548,7 +560,7 @@ protected function getElementRow(array $element, $delta, array $parent_options)
 
     $type = $webform_element->getPluginLabel();
     if ($webform_element instanceof WebformElement) {
-      if (isset($element['#type'])) {
+      if (!empty($element['#type'])) {
         $type = '[' . $element['#type'] . ']';
       }
       elseif (isset($element['#theme'])) {
diff --git a/web/modules/webform/modules/webform_ui/webform_ui.info.yml b/web/modules/webform/modules/webform_ui/webform_ui.info.yml
index 9e6f3f3303..a895ab31bf 100644
--- a/web/modules/webform/modules/webform_ui/webform_ui.info.yml
+++ b/web/modules/webform/modules/webform_ui/webform_ui.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/src/Commands/WebformCliService.php b/web/modules/webform/src/Commands/WebformCliService.php
index 3ea1f58a90..e012f06b7f 100644
--- a/web/modules/webform/src/Commands/WebformCliService.php
+++ b/web/modules/webform/src/Commands/WebformCliService.php
@@ -9,6 +9,7 @@
 use Drupal\Core\Serialization\Yaml;
 use Drupal\webform\Controller\WebformResultsExportController;
 use Drupal\webform\Entity\Webform;
+use Drupal\webform\Entity\WebformSubmission;
 use Drupal\webform\Form\WebformResultsClearForm;
 use Drupal\webform\Form\WebformSubmissionsPurgeForm;
 use Drupal\webform\Utility\WebformObjectHelper;
@@ -267,6 +268,16 @@ public function webform_drush_command() {
       'aliases' => ['wfr'],
     ];
 
+    $items['webform-remove-orphans'] = [
+      'description' => "Removes orphaned submissions where the submission's webform was deleted.",
+      'core' => ['8+'],
+      'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_ROOT,
+      'examples' => [
+        'webform-remove-orphans' => "Removes orphaned submissions where the submission's webform was deleted.",
+      ],
+      'aliases' => ['wfro'],
+    ];
+
     /* Docs */
 
     $items['webform-docs'] = [
@@ -884,6 +895,43 @@ public function drush_webform_repair() {
     \Drupal::service('cache.discovery')->deleteAll();
   }
 
+  /**
+   * {@inheritdoc}
+   *
+   * @see \Drupal\webform\Form\AdminConfig\WebformAdminConfigAdvancedForm::submitForm
+   */
+  public function drush_webform_remove_orphans() {
+    $webform_ids = [];
+    $config_factory = \Drupal::configFactory();
+    foreach ($config_factory->listAll('webform.webform.') as $webform_config_name) {
+      $webform_id = str_replace('webform.webform.', '', $webform_config_name);
+      $webform_ids[$webform_id] = $webform_id;
+    }
+
+   $sids = \Drupal::database()->select('webform_submission')
+      ->fields('webform_submission', ['sid'])
+      ->condition('webform_id', $webform_ids, 'NOT IN')
+      ->orderBy('sid')
+      ->execute()
+      ->fetchCol();
+
+    if (!$sids) {
+      $this->drush_print($this->dt('No orphaned submission found.'));
+      return;
+    }
+
+    $t_args = ['@total' => count($sids)];
+    if (!$this->drush_confirm($this->dt("Are you sure you want remove @total orphaned webform submissions?", $t_args))) {
+      return $this->drush_user_abort();
+    }
+
+    $this->drush_print($this->dt('Deleting @total orphaned webform submissions…', $t_args));
+    $submissions = WebformSubmission::loadMultiple($sids);
+    foreach ($submissions as $submission) {
+      $submission->delete();
+    }
+  }
+
   /******************************************************************************/
   // Docs.
   /******************************************************************************/
diff --git a/web/modules/webform/src/Commands/WebformCommands.php b/web/modules/webform/src/Commands/WebformCommands.php
index 12f37e735f..a21d2ea17a 100644
--- a/web/modules/webform/src/Commands/WebformCommands.php
+++ b/web/modules/webform/src/Commands/WebformCommands.php
@@ -2,7 +2,7 @@
 // @codingStandardsIgnoreFile
 
 /**
- * This is file was generated using Drush. DO NOT EDIT.
+ * This is file was generated using Drush. DO NOT EDIT. 
  *
  * @see drush webform-generate-commands
  * @see \Drupal\webform\Commands\DrushCliServiceBase::generate_commands_drush9
@@ -279,6 +279,22 @@ public function drush_webform_repair() {
     $this->cliService->drush_webform_repair();
   }
 
+  /****************************************************************************/
+  // drush webform:remove:orphans. DO NOT EDIT.
+  /****************************************************************************/
+
+  /**
+   * Removes orphaned submissions where the submission's webform was deleted.
+   *
+   * @command webform:remove:orphans
+   * @usage webform:remove:orphans
+   *   Removes orphaned submissions where the submission's webform was deleted.
+   * @aliases wfro,webform-remove-orphans
+   */
+  public function drush_webform_remove_orphans() {
+    $this->cliService->drush_webform_remove_orphans();
+  }
+
   /****************************************************************************/
   // drush webform:docs. DO NOT EDIT.
   /****************************************************************************/
@@ -346,4 +362,4 @@ public function drush_webform_generate_commands() {
     $this->cliService->drush_webform_generate_commands();
   }
 
-}
+}
\ No newline at end of file
diff --git a/web/modules/webform/src/Controller/WebformEntityController.php b/web/modules/webform/src/Controller/WebformEntityController.php
index d50cd27f3b..8329afd70f 100644
--- a/web/modules/webform/src/Controller/WebformEntityController.php
+++ b/web/modules/webform/src/Controller/WebformEntityController.php
@@ -9,6 +9,7 @@
 use Drupal\Core\Render\RendererInterface;
 use Drupal\Core\Serialization\Yaml;
 use Drupal\webform\Element\Webform as WebformElement;
+use Drupal\webform\Routing\WebformUncacheableResponse;
 use Drupal\webform\WebformInterface;
 use Drupal\webform\WebformRequestInterface;
 use Drupal\webform\WebformSubmissionInterface;
@@ -16,7 +17,7 @@
 use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\HttpFoundation\Response;
+use Drupal\Core\Cache\CacheableResponse;
 
 /**
  * Provides route responses for Webform entity.
@@ -103,12 +104,17 @@ public function addForm(Request $request, WebformInterface $webform) {
    * @param \Drupal\webform\WebformInterface $webform
    *   The webform.
    *
-   * @return \Symfony\Component\HttpFoundation\Response
+   * @return \Symfony\Component\HttpFoundation\Response|\Drupal\Core\Cache\CacheableResponse
    *   The response object.
    */
   public function css(Request $request, WebformInterface $webform) {
     $assets = $webform->getAssets();
-    return new Response($assets['css'], 200, ['Content-Type' => 'text/css']);
+    if ($webform->access('update')) {
+      return new WebformUncacheableResponse($assets['css'], 200, ['Content-Type' => 'text/css']);
+    }
+    else {
+      return new CacheableResponse($assets['css'], 200, ['Content-Type' => 'text/css']);
+    }
   }
 
   /**
@@ -119,12 +125,17 @@ public function css(Request $request, WebformInterface $webform) {
    * @param \Drupal\webform\WebformInterface $webform
    *   The webform.
    *
-   * @return \Symfony\Component\HttpFoundation\Response
+   * @return \Symfony\Component\HttpFoundation\Response|\Drupal\Core\Cache\CacheableResponse
    *   The response object.
    */
   public function javascript(Request $request, WebformInterface $webform) {
     $assets = $webform->getAssets();
-    return new Response($assets['javascript'], 200, ['Content-Type' => 'text/javascript']);
+    if ($webform->access('update')) {
+      return new WebformUncacheableResponse($assets['javascript'], 200, ['Content-Type' => 'text/javascript']);
+    }
+    else {
+      return new CacheableResponse($assets['javascript'], 200, ['Content-Type' => 'text/javascript']);
+    }
   }
 
   /**
diff --git a/web/modules/webform/src/Element/WebformActions.php b/web/modules/webform/src/Element/WebformActions.php
index 9e415aa759..03e9bb7d50 100644
--- a/web/modules/webform/src/Element/WebformActions.php
+++ b/web/modules/webform/src/Element/WebformActions.php
@@ -125,14 +125,18 @@ public static function processWebformActions(&$element, FormStateInterface $form
       }
     }
 
+    // Hide form actions only if the element is accessible.
+    // This prevents form from having no actions.
+    $has_access = (!isset($element['#access']) || $element['#access'] === TRUE);
+    if ($has_access) {
+      $complete_form['actions']['#access'] = FALSE;
+    }
+
     // Hide actions element if no buttons are visible (i.e. #access = FALSE).
     if (!$has_visible_button) {
       $element['#access'] = FALSE;
     }
 
-    // Hide form actions.
-    $complete_form['actions']['#access'] = FALSE;
-
     return $element;
   }
 
diff --git a/web/modules/webform/src/Element/WebformCodeMirror.php b/web/modules/webform/src/Element/WebformCodeMirror.php
index ed5f598b04..e03fedd078 100644
--- a/web/modules/webform/src/Element/WebformCodeMirror.php
+++ b/web/modules/webform/src/Element/WebformCodeMirror.php
@@ -46,6 +46,7 @@ public function getInfo() {
       '#input' => TRUE,
       '#mode' => 'text',
       '#skip_validation' => FALSE,
+      '#decode_value' => FALSE,
       '#cols' => 60,
       '#rows' => 5,
       '#wrap' => TRUE,
@@ -158,7 +159,9 @@ public static function validateWebformCodeMirror(&$element, FormStateInterface $
     }
     else {
       // If editing YAML and #default_value is an array, decode #value.
-      if ($element['#mode'] == 'yaml' && (isset($element['#default_value']) && is_array($element['#default_value']))) {
+      if ($element['#mode'] == 'yaml'
+        && (isset($element['#default_value']) && is_array($element['#default_value']) || $element['#decode_value'])
+      ) {
         // Handle rare case where single array value is not parsed correctly.
         if (preg_match('/^- (.*?)\s*$/', $element['#value'], $match)) {
           $value = [$match[1]];
diff --git a/web/modules/webform/src/Element/WebformEmailMultiple.php b/web/modules/webform/src/Element/WebformEmailMultiple.php
index a128f76594..1a61b3ae9b 100644
--- a/web/modules/webform/src/Element/WebformEmailMultiple.php
+++ b/web/modules/webform/src/Element/WebformEmailMultiple.php
@@ -61,7 +61,7 @@ public static function validateWebformEmailMultiple(&$element, FormStateInterfac
       $values = preg_split('/\s*,\s*/', $value);
       // Validate email.
       foreach ($values as $value) {
-        // Allow tokens to be be included in multiple email list by skipping
+        // Allow tokens to be included in multiple email list by skipping
         // validation if a token is present.
         if (!empty($element['#allow_tokens'] && preg_match('/\[.+\]/', $value))) {
           continue;
diff --git a/web/modules/webform/src/Element/WebformScale.php b/web/modules/webform/src/Element/WebformScale.php
new file mode 100644
index 0000000000..7b2695fe14
--- /dev/null
+++ b/web/modules/webform/src/Element/WebformScale.php
@@ -0,0 +1,122 @@
+<?php
+
+namespace Drupal\webform\Element;
+
+use Drupal\Component\Utility\Html as HtmlUtility;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\Element\Radios;
+
+/**
+ * Provides a webform element for a scale (1-5).
+ *
+ * @FormElement("webform_scale")
+ */
+class WebformScale extends Radios {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getInfo() {
+    return parent::getInfo() + [
+      '#min' => 1,
+      '#max' => 5,
+      '#min_text' => '',
+      '#max_text' => '',
+      '#scale_size' => 'medium',
+      '#scale_type' => 'circle',
+      '#scale_text' => 'below',
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function processRadios(&$element, FormStateInterface $form_state, &$complete_form) {
+    // Add text.
+    $scale_text = [];
+    if ($element['#min_text'] || $element['#max_text']) {
+      $classes = [
+        'webform-scale-text',
+        'webform-scale-text-' . $element['#scale_text'],
+      ];
+      $scale_text = [
+        '#prefix' => '<div class="' . implode(' ', $classes) . '">',
+        '#suffix' => '</div>',
+      ];
+      if ($element['#min_text']) {
+        $scale_text['min'] = [
+          '#markup' => $element['#min_text'],
+          '#prefix' => '<div class="webform-scale-text-min">',
+          '#suffix' => '</div>',
+        ];
+      }
+      if ($element['#max_text']) {
+        $scale_text['max'] = [
+          '#prefix' => '<div class="webform-scale-text-max">',
+          '#suffix' => '</div>',
+          '#markup' => $element['#max_text'],
+        ];
+      }
+    }
+
+    // Scale.
+    $classes = [
+      'webform-scale',
+      'webform-scale-' . $element['#scale_type'],
+      'webform-scale-' . $element['#scale_size'],
+      'webform-scale-' . $element['#min'] . '-to-' . $element['#max'],
+    ];
+    $element['scale'] = [
+      '#prefix' => '<div class="' . implode(' ', $classes) . '">',
+      '#suffix' => '</div>',
+    ];
+
+    // Text above.
+    if ($scale_text && $element['#scale_text'] === 'above') {
+      $element['scale']['text'] = $scale_text;
+    }
+
+    // Options.
+    $element['scale']['options'] = [
+      '#prefix' => '<div class="webform-scale-options">',
+      '#suffix' => '</div>',
+    ];
+    $ratings = range($element['#min'], $element['#max']);
+    $element['#options'] = array_combine($ratings, $ratings);
+    foreach ($element['#options'] as $key => $choice) {
+      $parents_for_id = array_merge($element['#parents'], [$key]);
+
+      $element['scale']['options'] += [$key => []];
+      $element['scale']['options'][$key] += [
+        '#type' => 'radio',
+        '#title' => $choice,
+        '#return_value' => $key,
+        '#default_value' => isset($element['#default_value']) ? $element['#default_value'] : FALSE,
+        '#attributes' => $element['#attributes'],
+        '#parents' => $element['#parents'],
+        '#id' => HtmlUtility::getUniqueId('edit-' . implode('-', $parents_for_id)),
+        '#ajax' => isset($element['#ajax']) ? $element['#ajax'] : NULL,
+        '#error_no_message' => TRUE,
+        '#prefix' => '<div class="webform-scale-option">',
+        '#suffix' => '</div>',
+      ];
+
+      // Add .webform-scale-N class to the radio.
+      $element['scale']['options'][$key]['#attributes']['class'][] = 'webform-scale-' . $key;
+
+      // Add .visually-hidden class to the radio.
+      $element['scale']['options'][$key]['#attributes']['class'][] = 'visually-hidden';
+    }
+
+    // Text below.
+    if ($scale_text && $element['#scale_text'] === 'below') {
+      $element['scale']['text'] = $scale_text;
+    }
+
+    // Add scale library.
+    $element['#attached']['library'][] = 'webform/webform.element.scale';
+
+    return $element;
+  }
+
+}
diff --git a/web/modules/webform/src/Element/WebformSignature.php b/web/modules/webform/src/Element/WebformSignature.php
index 3b26d6a9da..173948f027 100644
--- a/web/modules/webform/src/Element/WebformSignature.php
+++ b/web/modules/webform/src/Element/WebformSignature.php
@@ -42,6 +42,11 @@ public function getInfo() {
   public static function processWebformSignature(&$element, FormStateInterface $form_state, &$complete_form) {
     // Remove 'for' from the element's label.
     $element['#label_attributes']['webform-remove-for-attribute'] = TRUE;
+
+    // Add validate callback.
+    $element += ['#element_validate' => []];
+    array_unshift($element['#element_validate'], [get_called_class(), 'validateWebformSignature']);
+
     return $element;
   }
 
@@ -79,4 +84,62 @@ public static function preRenderWebformSignature(array $element) {
     return $element;
   }
 
+  /**
+  +   * Webform element validation handler for #type 'signature'.
+  +   */
+  public static function validateWebformSignature(&$element, FormStateInterface $form_state, &$complete_form) {
+    $value = $element['#value'];
+    if (!static::isSignatureValid($value)) {
+      $t_args = ['@title' => isset($element['#title']) ? $element['#title'] : t('Form')];
+      $form_state->setError($element, t('@title contains an invalid signature.', $t_args));
+    }
+  }
+
+  /**
+   * Determine that signature PNG is valid.
+   *
+   * @param string $value
+   *   Upload base64 png image.
+   *
+   * @return bool
+   *   TRUE if signature PNG is valid.
+   */
+  public static function isSignatureValid($value) {
+    if (empty($value)) {
+      return TRUE;
+    }
+
+    // Make sure the signature is a png.
+    if (strpos($value, 'data:image/png;base64,') !== 0) {
+      return FALSE;
+    }
+
+    // Make sure signature's image size can be read.
+    /** @var \Drupal\Core\File\FileSystemInterface $file_system */
+    $file_system = \Drupal::service('file_system');
+    $temp_image = $file_system->tempnam('temporary://', 'webform_signature_');
+    $encoded_image = explode(',', $value)[1];
+    $decoded_image = base64_decode($encoded_image);
+    file_put_contents($temp_image, $decoded_image);
+    $image_size = getimagesize($temp_image);
+    if (!$image_size) {
+      return FALSE;
+    }
+
+    // Make sure signature is not larger than a 500 kb.
+    if (filesize($temp_image) > 500000) {
+      return FALSE;
+    }
+
+    // Make sure the signature contains no colors.
+    $image = imagecreatefrompng($temp_image);
+    $number_of_colors = imagecolorstotal($image);
+    imagedestroy($image);
+    if ($number_of_colors > 0) {
+      return FALSE;
+    }
+
+    return TRUE;
+  }
+
 }
diff --git a/web/modules/webform/src/Element/WebformSubmissionViewsReplace.php b/web/modules/webform/src/Element/WebformSubmissionViewsReplace.php
index cd1df1b82c..55c72c5201 100644
--- a/web/modules/webform/src/Element/WebformSubmissionViewsReplace.php
+++ b/web/modules/webform/src/Element/WebformSubmissionViewsReplace.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\webform\Element;
 
+use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element\FormElement;
 
@@ -41,7 +42,7 @@ public static function valueCallback(&$element, $input, FormStateInterface $form
   }
 
   /**
-   * Processes a ng webform submission views replacement element.
+   * Processes a webform submission views replacement element.
    */
   public static function processWebformSubmissionViewsReplace(&$element, FormStateInterface $form_state, &$complete_form) {
     $is_global = (!empty($element['#global'])) ? TRUE : FALSE;
@@ -110,7 +111,26 @@ public static function processWebformSubmissionViewsReplace(&$element, FormState
       '#element_validate' => [['\Drupal\webform\Utility\WebformElementHelper', 'filterValues']],
     ];
 
+    // Add validate callback that extracts the array of items.
+    $element += ['#element_validate' => []];
+    array_unshift($element['#element_validate'], [get_called_class(), 'validateWebformSubmissionViewsReplace']);
+
     return $element;
   }
 
+  /**
+   * Validates webform submission views replacement element.
+   */
+  public static function validateWebformSubmissionViewsReplace(&$element, FormStateInterface $form_state, &$complete_form) {
+    $values = NestedArray::getValue($form_state->getValues(), $element['#parents']);
+
+    // Remove empty view replace references.
+    if (empty($values['global_routes']) && empty($values['webform_routes']) && empty($values['node_routes'])) {
+      $values = [];
+    }
+
+    $element['#value'] = $values;
+    $form_state->setValueForElement($element, $values);
+  }
+
 }
diff --git a/web/modules/webform/src/Element/WebformTable.php b/web/modules/webform/src/Element/WebformTable.php
new file mode 100644
index 0000000000..96bd1bcd2b
--- /dev/null
+++ b/web/modules/webform/src/Element/WebformTable.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Drupal\webform\Element;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\Element\Table;
+
+/**
+ * Provides a render element for webform table.
+ *
+ * @FormElement("webform_table")
+ */
+class WebformTable extends Table {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getInfo() {
+    return parent::getInfo() + [
+      '#theme_wrappers' => ['form_element'],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function processTable(&$element, FormStateInterface $form_state, &$complete_form) {
+    // @see \Drupal\Core\Render\Element\Table::getInfo
+    $element['#input'] = TRUE;
+    $element['#tableselect'] = FALSE;
+    $element['#tabledrag'] = FALSE;
+    $element['#tree'] = FALSE;
+
+    // Add .webform-table class to the table element.
+    $element['#attributes']['class'][] = 'webform-table';
+
+    // Remove 'for' attribute from form wrapper's label.
+    $element['#label_attributes']['webform-remove-for-attribute'] = TRUE;
+
+    // Add webform table CSS.
+    $element['#attached']['library'][] = 'webform/webform.element.table';
+
+    return $element;
+  }
+
+}
diff --git a/web/modules/webform/src/Element/WebformTableRow.php b/web/modules/webform/src/Element/WebformTableRow.php
new file mode 100644
index 0000000000..0d63f5cc38
--- /dev/null
+++ b/web/modules/webform/src/Element/WebformTableRow.php
@@ -0,0 +1,51 @@
+<?php
+
+namespace Drupal\webform\Element;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\Element\RenderElement;
+
+/**
+ * Provides a render element for webform table row.
+ *
+ * @FormElement("webform_table_row")
+ */
+class WebformTableRow extends RenderElement {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getInfo() {
+    $class = get_class($this);
+    return [
+      '#optional' => FALSE,
+      '#process' => [
+        [$class, 'processTableRow'],
+      ],
+      '#pre_render' => [],
+    ];
+  }
+
+  /**
+   * Processes a webfrom table row element.
+   *
+   * @param array $element
+   *   An associative array containing the properties and children of the
+   *   container.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The current state of the form.
+   * @param array $complete_form
+   *   The complete form structure.
+   *
+   * @return array
+   *   The processed element.
+   */
+  public static function processTableRow(&$element, FormStateInterface $form_state, &$complete_form) {
+    $element['#attributes']['class'][] = 'webform-table-row';
+    if (!empty($element['#states'])) {
+      webform_process_states($element);
+    }
+    return $element;
+  }
+
+}
diff --git a/web/modules/webform/src/Element/WebformTermReferenceTrait.php b/web/modules/webform/src/Element/WebformTermReferenceTrait.php
index e966a31c25..517c0d1b70 100644
--- a/web/modules/webform/src/Element/WebformTermReferenceTrait.php
+++ b/web/modules/webform/src/Element/WebformTermReferenceTrait.php
@@ -30,6 +30,12 @@ public static function setOptions(array &$element) {
     else {
       $element['#options'] = static::getOptionsTree($element, $language);
     }
+
+    // Add the vocabulary to the cache tags.
+    // Issue #2920913: The taxonomy_term_list cache should be invalidated
+    // on a vocabulary-by-vocabulary basis
+    // @see https://www.drupal.org/project/drupal/issues/2920913
+    $element['#cache']['tags'][] = 'taxonomy_term_list';
   }
 
   /**
@@ -56,6 +62,10 @@ protected static function getOptionsBreadcrumb(array $element, $language) {
     foreach ($tree as $item) {
       // Set the item in the correct language for display.
       $item = $entity_repository->getTranslationFromContext($item);
+      if (!$item->access('view')) {
+        continue;
+      }
+
       $breadcrumb[$item->depth] = $item->getName();
       $breadcrumb = array_slice($breadcrumb, 0, $item->depth + 1);
       $options[$item->id()] = implode($element['#breadcrumb_delimiter'], $breadcrumb);
@@ -86,6 +96,10 @@ protected static function getOptionsTree(array $element, $language) {
     foreach ($tree as $item) {
       // Set the item in the correct language for display.
       $item = $entity_repository->getTranslationFromContext($item);
+      if (!$item->access('view')) {
+        continue;
+      }
+
       $options[$item->id()] = str_repeat($element['#tree_delimiter'], $item->depth) . $item->getName();
     }
     return $options;
diff --git a/web/modules/webform/src/Element/WebformVideoFile.php b/web/modules/webform/src/Element/WebformVideoFile.php
index dd8ed3ded6..23fee980df 100644
--- a/web/modules/webform/src/Element/WebformVideoFile.php
+++ b/web/modules/webform/src/Element/WebformVideoFile.php
@@ -12,6 +12,6 @@ class WebformVideoFile extends WebformManagedFileBase {
   /**
    * {@inheritdoc}
    */
-  protected static $accept = 'video/*';
+  protected static $accept = 'video/mp4,video/x-m4v,video/*';
 
 }
diff --git a/web/modules/webform/src/Entity/Webform.php b/web/modules/webform/src/Entity/Webform.php
index f5135e7a4a..f2d6711f88 100644
--- a/web/modules/webform/src/Entity/Webform.php
+++ b/web/modules/webform/src/Entity/Webform.php
@@ -1453,6 +1453,7 @@ protected function initElements() {
     }
 
     if ($elements !== FALSE) {
+      $elements = WebformElementHelper::removeIgnoredProperties($elements);
       $this->initElementsRecursive($elements);
       $this->invokeHandlers('alterElements', $elements, $this);
     }
@@ -1501,9 +1502,6 @@ protected function initElementsRecursive(array &$elements, $parent = '', $depth
     /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
     $element_manager = \Drupal::service('plugin.manager.webform.element');
 
-    // Remove ignored properties.
-    $elements = WebformElementHelper::removeIgnoredProperties($elements);
-
     foreach ($elements as $key => &$element) {
       if (!WebformElementHelper::isElement($element, $key)) {
         continue;
diff --git a/web/modules/webform/src/Entity/Webform.php.orig b/web/modules/webform/src/Entity/Webform.php.orig
new file mode 100644
index 0000000000..f5135e7a4a
--- /dev/null
+++ b/web/modules/webform/src/Entity/Webform.php.orig
@@ -0,0 +1,3056 @@
+<?php
+
+namespace Drupal\webform\Entity;
+
+use Drupal\Component\Utility\NestedArray;
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Cache\Cache;
+use Drupal\Core\Config\Entity\ConfigEntityInterface;
+use Drupal\Core\Serialization\Yaml;
+use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
+use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\Core\Language\LanguageInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\user\Entity\User;
+use Drupal\user\UserInterface;
+use Drupal\webform\Plugin\WebformElement\WebformActions;
+use Drupal\webform\Plugin\WebformElement\WebformWizardPage;
+use Drupal\webform\Plugin\WebformElementAssetInterface;
+use Drupal\webform\Plugin\WebformElementAttachmentInterface;
+use Drupal\webform\Plugin\WebformElementComputedInterface;
+use Drupal\webform\Plugin\WebformElementVariantInterface;
+use Drupal\webform\Plugin\WebformElementWizardPageInterface;
+use Drupal\webform\Plugin\WebformHandlerMessageInterface;
+use Drupal\webform\Plugin\WebformVariantInterface;
+use Drupal\webform\Plugin\WebformVariantPluginCollection;
+use Drupal\webform\Utility\WebformElementHelper;
+use Drupal\webform\Utility\WebformReflectionHelper;
+use Drupal\webform\Plugin\WebformHandlerInterface;
+use Drupal\webform\Plugin\WebformHandlerPluginCollection;
+use Drupal\webform\Utility\WebformTextHelper;
+use Drupal\webform\Utility\WebformYaml;
+use Drupal\webform\WebformException;
+use Drupal\webform\WebformInterface;
+use Drupal\webform\WebformSubmissionInterface;
+use Drupal\webform\WebformSubmissionStorageInterface;
+
+/**
+ * Defines the webform entity.
+ *
+ * @ConfigEntityType(
+ *   id = "webform",
+ *   label = @Translation("Webform"),
+ *   label_collection = @Translation("Webforms"),
+ *   label_singular = @Translation("webform"),
+ *   label_plural = @Translation("webforms"),
+ *   label_count = @PluralTranslation(
+ *     singular = "@count webform",
+ *     plural = "@count webforms",
+ *   ),
+ *   handlers = {
+ *     "storage" = "\Drupal\webform\WebformEntityStorage",
+ *     "view_builder" = "Drupal\webform\WebformEntityViewBuilder",
+ *     "list_builder" = "Drupal\webform\WebformEntityListBuilder",
+ *     "access" = "Drupal\webform\WebformEntityAccessControlHandler",
+ *     "form" = {
+ *       "add" = "Drupal\webform\WebformEntityAddForm",
+ *       "duplicate" = "Drupal\webform\WebformEntityAddForm",
+ *       "delete" = "Drupal\webform\WebformEntityDeleteForm",
+ *       "edit" = "Drupal\webform\WebformEntityElementsForm",
+ *       "export" = "Drupal\webform\WebformEntityExportForm",
+ *       "settings" = "Drupal\webform\EntitySettings\WebformEntitySettingsGeneralForm",
+ *       "settings_form" = "Drupal\webform\EntitySettings\WebformEntitySettingsFormForm",
+ *       "settings_submissions" = "Drupal\webform\EntitySettings\WebformEntitySettingsSubmissionsForm",
+ *       "settings_confirmation" = "Drupal\webform\EntitySettings\WebformEntitySettingsConfirmationForm",
+ *       "settings_assets" = "Drupal\webform\EntitySettings\WebformEntitySettingsAssetsForm",
+ *       "settings_access" = "Drupal\webform\EntitySettings\WebformEntitySettingsAccessForm",
+ *       "handlers" = "Drupal\webform\WebformEntityHandlersForm",
+ *       "variants" = "Drupal\webform\WebformEntityVariantsForm",
+ *     }
+ *   },
+ *   admin_permission = "administer webform",
+ *   bundle_of = "webform_submission",
+ *   static_cache = TRUE,
+ *   entity_keys = {
+ *     "id" = "id",
+ *     "label" = "title",
+ *   },
+ *   links = {
+ *     "canonical" = "/webform/{webform}",
+ *     "access-denied" = "/webform/{webform}/access-denied",
+ *     "submissions" = "/webform/{webform}/submissions",
+ *     "add-form" = "/webform/{webform}",
+ *     "edit-form" = "/admin/structure/webform/manage/{webform}/elements",
+ *     "test-form" = "/webform/{webform}/test",
+ *     "duplicate-form" = "/admin/structure/webform/manage/{webform}/duplicate",
+ *     "delete-form" = "/admin/structure/webform/manage/{webform}/delete",
+ *     "export-form" = "/admin/structure/webform/manage/{webform}/export",
+ *     "settings" = "/admin/structure/webform/manage/{webform}/settings",
+ *     "settings-form" = "/admin/structure/webform/manage/{webform}/settings/form",
+ *     "settings-submissions" = "/admin/structure/webform/manage/{webform}/settings/submissions",
+ *     "settings-confirmation" = "/admin/structure/webform/manage/{webform}/settings/confirmation",
+ *     "settings-assets" = "/admin/structure/webform/manage/{webform}/settings/assets",
+ *     "settings-access" = "/admin/structure/webform/manage/{webform}/settings/access",
+ *     "handlers" = "/admin/structure/webform/manage/{webform}/handlers",
+ *     "variants" = "/admin/structure/webform/manage/{webform}/variants",
+ *     "results-submissions" = "/admin/structure/webform/manage/{webform}/results/submissions",
+ *     "results-export" = "/admin/structure/webform/manage/{webform}/results/download",
+ *     "results-log" = "/admin/structure/webform/manage/{webform}/results/log",
+ *     "results-clear" = "/admin/structure/webform/manage/{webform}/results/clear",
+ *     "collection" = "/admin/structure/webform",
+ *   },
+ *   config_export = {
+ *     "status",
+ *     "open",
+ *     "close",
+ *     "weight",
+ *     "uid",
+ *     "template",
+ *     "archive",
+ *     "id",
+ *     "uuid",
+ *     "title",
+ *     "description",
+ *     "category",
+ *     "elements",
+ *     "css",
+ *     "javascript",
+ *     "settings",
+ *     "access",
+ *     "handlers",
+ *     "variants",
+ *     "third_party_settings",
+ *   },
+ *   lookup_keys = {
+ *     "status",
+ *     "template",
+ *   },
+ * )
+ */
+class Webform extends ConfigEntityBundleBase implements WebformInterface {
+
+  use StringTranslationTrait;
+
+  /**
+   * The webform ID.
+   *
+   * @var string
+   */
+  protected $id;
+
+  /**
+   * The webform UUID.
+   *
+   * @var string
+   */
+  protected $uuid;
+
+  /**
+   * The webform's current operation.
+   *
+   * @var string
+   */
+  protected $operation;
+
+  /**
+   * The webform override state.
+   *
+   * When set to TRUE the webform can't not be saved.
+   *
+   * @var bool
+   */
+  protected $override = FALSE;
+
+  /**
+   * The webform status.
+   *
+   * @var string
+   */
+  protected $status = WebformInterface::STATUS_OPEN;
+
+  /**
+   * The webform open date/time.
+   *
+   * @var bool
+   */
+  protected $open;
+
+  /**
+   * The webform close date/time.
+   *
+   * @var bool
+   */
+  protected $close;
+
+  /**
+   * The webform weight.
+   *
+   * @var int
+   */
+  protected $weight = 0;
+
+  /**
+   * The webform template indicator.
+   *
+   * @var bool
+   */
+  protected $template = FALSE;
+
+  /**
+   * The webform archive indicator.
+   *
+   * @var bool
+   */
+  protected $archive = FALSE;
+
+  /**
+   * The webform title.
+   *
+   * @var string
+   */
+  protected $title;
+
+  /**
+   * The webform description.
+   *
+   * @var string
+   */
+  protected $description;
+
+  /**
+   * The webform options category.
+   *
+   * @var string
+   */
+  protected $category;
+
+  /**
+   * The owner's uid.
+   *
+   * @var int
+   */
+  protected $uid;
+
+  /**
+   * The webform settings.
+   *
+   * @var array
+   */
+  protected $settings = [];
+
+  /**
+   * The webform settings original.
+   *
+   * @var string
+   */
+  protected $settingsOriginal;
+
+  /**
+   * The webform access controls.
+   *
+   * @var array
+   */
+  protected $access = [];
+
+  /**
+   * The webform elements.
+   *
+   * @var string
+   */
+  protected $elements;
+
+  /**
+   * The CSS style sheet.
+   *
+   * @var string
+   */
+  protected $css = '';
+
+  /**
+   * The JavaScript.
+   *
+   * @var string
+   */
+  protected $javascript = '';
+
+  /**
+   * The array of webform handlers for this webform.
+   *
+   * @var array
+   */
+  protected $handlers = [];
+
+  /**
+   * Holds the collection of webform handlers that are used by this webform.
+   *
+   * @var \Drupal\webform\Plugin\WebformHandlerPluginCollection
+   */
+  protected $handlersCollection;
+
+  /**
+   * The array of webform variants for this webform.
+   *
+   * @var array
+   */
+  protected $variants = [];
+
+  /**
+   * Holds the collection of webform variants that are used by this webform.
+   *
+   * @var \Drupal\webform\Plugin\WebformVariantsPluginCollection
+   */
+  protected $variantsCollection;
+
+  /**
+   * The webform elements original.
+   *
+   * @var string
+   */
+  protected $elementsOriginal;
+
+  /**
+   * The webform elements decoded.
+   *
+   * @var array
+   */
+  protected $elementsDecoded;
+
+  /**
+   * The webform elements initializes (and decoded).
+   *
+   * @var array
+   */
+  protected $elementsInitialized;
+
+  /**
+   * The webform elements decoded and flattened.
+   *
+   * @var array
+   */
+  protected $elementsDecodedAndFlattened;
+
+  /**
+   * The webform elements initialized and flattened.
+   *
+   * @var array
+   */
+  protected $elementsInitializedAndFlattened;
+
+  /**
+   * The webform elements initialized, flattened, and has value.
+   *
+   * @var array
+   */
+  protected $elementsInitializedFlattenedAndHasValue;
+
+  /**
+   * The webform elements translations.
+   *
+   * @var array
+   */
+  protected $elementsTranslations;
+
+  /**
+   * Track the elements that are prepopulated.
+   *
+   * @var array
+   */
+  protected $elementsPrepopulate = [];
+
+  /**
+   * Track the elements that are 'webform_actions' (aka submit buttons).
+   *
+   * @var array
+   */
+  protected $elementsActions = [];
+
+  /**
+   * Track the elements that are 'webform_pages' (aka Wizard pages).
+   *
+   * @var array
+   */
+  protected $elementsWizardPages = [];
+
+  /**
+   * Track managed file elements.
+   *
+   * @var array
+   */
+  protected $elementsManagedFiles = [];
+
+  /**
+   * Track attachment elements.
+   *
+   * @var array
+   */
+  protected $elementsAttachments = [];
+
+  /**
+   * Track computed elements.
+   *
+   * @var array
+   */
+  protected $elementsComputed = [];
+
+  /**
+   * Track variant elements.
+   *
+   * @var array
+   */
+  protected $elementsVariant = [];
+
+  /**
+   * Track elements CSS.
+   *
+   * @var array
+   */
+  protected $elementsCss = [];
+
+  /**
+   * Track elements JavaScript.
+   *
+   * @var array
+   */
+  protected $elementsJavaScript = [];
+
+  /**
+   * A webform's default data extracted from each element's default value or value.
+   *
+   * @var array
+   */
+  protected $elementsDefaultData = [];
+
+  /**
+   * The webform pages.
+   *
+   * @var array
+   */
+  protected $pages;
+
+  /**
+   * Track if the webform is using a flexbox layout.
+   *
+   * @var bool
+   */
+  protected $hasFlexboxLayout = FALSE;
+
+  /**
+   * Track if the webform has container.
+   *
+   * @var bool
+   */
+  protected $hasContainer = FALSE;
+
+  /**
+   * Track if the webform has conditions (i.e. #states).
+   *
+   * @var bool
+   */
+  protected $hasConditions = FALSE;
+
+  /**
+   * Track if the webform has required elements.
+   *
+   * @var bool
+   */
+  protected $hasRequired = FALSE;
+
+  /**
+   * Track if the webform has translations.
+   *
+   * @var bool
+   */
+  protected $hasTranslations;
+
+  /**
+   * Track if the webform has message handler.
+   *
+   * @var bool
+   */
+  protected $hasMessageHandler;
+
+  /**
+   * Track if a webform handler requires anonymous submission tracking .
+   *
+   * @var bool
+   */
+  protected $hasAnonymousSubmissionTrackingHandler;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getLangcode() {
+    return $this->langcode;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getWeight() {
+    return $this->weight;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getOwner() {
+    return $this->uid ? User::load($this->uid) : NULL;
+  }
+
+  /**
+   * Sets the entity owner's user entity.
+   *
+   * @param \Drupal\user\UserInterface $account
+   *   The owner user entity.
+   *
+   * @return $this
+   */
+  public function setOwner(UserInterface $account) {
+    $this->uid = $account->id();
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getOwnerId() {
+    return $this->uid;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setOwnerId($uid) {
+    $this->uid = ($uid) ? $uid : NULL;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getOperation() {
+    return $this->operation;
+
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setOperation($operation) {
+    $this->operation = $operation;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isTest() {
+    return ($this->operation === 'test') ? TRUE : FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setOverride($override = TRUE) {
+    $this->override = $override;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isOverridden() {
+    return $this->override;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setStatus($status) {
+    if ($status === NULL || $status === WebformInterface::STATUS_SCHEDULED) {
+      $this->status = WebformInterface::STATUS_SCHEDULED;
+    }
+    elseif ($status === WebformInterface::STATUS_OPEN) {
+      $this->status = WebformInterface::STATUS_OPEN;
+    }
+    elseif ($status === WebformInterface::STATUS_CLOSED) {
+      $this->status = WebformInterface::STATUS_CLOSED;
+    }
+    else {
+      $this->status = ((bool) $status) ? WebformInterface::STATUS_OPEN : WebformInterface::STATUS_CLOSED;
+    }
+
+    // Clear open and close if status is not scheduled.
+    if ($this->status !== WebformInterface::STATUS_SCHEDULED) {
+      $this->open = NULL;
+      $this->close = NULL;
+    }
+
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function status() {
+    return $this->isOpen();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isOpen() {
+    // Archived webforms are always closed.
+    if ($this->isArchived()) {
+      return FALSE;
+    }
+
+    switch ($this->status) {
+      case WebformInterface::STATUS_OPEN:
+        return TRUE;
+
+      case WebformInterface::STATUS_CLOSED:
+        return FALSE;
+
+      case WebformInterface::STATUS_SCHEDULED:
+        $is_opened = TRUE;
+        if ($this->open && strtotime($this->open) > time()) {
+          $is_opened = FALSE;
+        }
+
+        $is_closed = FALSE;
+        if ($this->close && strtotime($this->close) < time()) {
+          $is_closed = TRUE;
+        }
+
+        return ($is_opened && !$is_closed) ? TRUE : FALSE;
+    }
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isClosed() {
+    return !$this->isOpen();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isScheduled() {
+    return ($this->status === WebformInterface::STATUS_SCHEDULED);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isOpening() {
+    return ($this->isScheduled() && ($this->open && strtotime($this->open) > time())) ? TRUE : FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isTemplate() {
+    return $this->template ? TRUE : FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isArchived() {
+    return $this->archive ? TRUE : FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isConfidential() {
+    return $this->getSetting('form_confidential');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasRemoteAddr() {
+    return (!$this->isConfidential() && $this->getSetting('form_remote_addr')) ? TRUE : FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isResultsDisabled() {
+    $elements = $this->getElementsDecoded();
+    $settings = $this->getSettings();
+    return (!empty($settings['results_disabled']) || !empty($elements['#method'])) ? TRUE : FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasSubmissions() {
+    /** @var \Drupal\webform\WebformSubmissionStorageInterface $submission_storage */
+    $submission_storage = \Drupal::entityTypeManager()->getStorage('webform_submission');
+    return ($submission_storage->getTotal($this)) ? TRUE : FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasSubmissionLog() {
+    return $this->getSetting('submission_log', TRUE) ?: FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasTranslations() {
+    if (isset($this->hasTranslations)) {
+      return $this->hasTranslations;
+    }
+
+    // Make sure the config translation module is enabled.
+    if (!\Drupal::moduleHandler()->moduleExists('config_translation')) {
+      $this->hasTranslations = FALSE;
+      return $this->hasTranslations;
+    }
+
+    /** @var \Drupal\locale\LocaleConfigManager $local_config_manager */
+    $local_config_manager = \Drupal::service('locale.config_manager');
+    $languages = \Drupal::languageManager()->getLanguages();
+    foreach ($languages as $langcode => $language) {
+      if ($local_config_manager->hasTranslation('webform.webform.' . $this->id(), $langcode)) {
+        $this->hasTranslations = TRUE;
+        return $this->hasTranslations;
+      }
+    }
+
+    $this->hasTranslations = FALSE;
+    return $this->hasTranslations;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasPage() {
+    $settings = $this->getSettings();
+    return $settings['page'] ? TRUE : FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasManagedFile() {
+    $this->initElements();
+    return (!empty($this->elementsManagedFiles)) ? TRUE : FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasAttachments() {
+    $this->initElements();
+    return (!empty($this->elementsAttachments)) ? TRUE : FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasComputed() {
+    $this->initElements();
+    return (!empty($this->elementsComputed)) ? TRUE : FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasVariants() {
+    $this->initElements();
+    return (!empty($this->elementsVariant)) ? TRUE : FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasFlexboxLayout() {
+    $this->initElements();
+    return $this->hasFlexboxLayout;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasContainer() {
+    $this->initElements();
+    return $this->hasContainer;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasConditions() {
+    $this->initElements();
+    return $this->hasConditions;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasRequired() {
+    $this->initElements();
+    return $this->hasRequired;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasActions() {
+    return $this->getNumberOfActions() ? TRUE : FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getNumberOfActions() {
+    $this->initElements();
+    return count($this->elementsActions);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasPreview() {
+    return ($this->getSetting('preview') != DRUPAL_DISABLED);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasWizardPages() {
+    return $this->getNumberOfWizardPages() ? TRUE : FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getNumberOfWizardPages() {
+    $this->initElements();
+    return count($this->elementsWizardPages);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDescription() {
+    return $this->description;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setDescription($description) {
+    $this->description = $description;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getAssets() {
+    $this->initElements();
+
+    // Css.
+    $css = [];
+    $shared_css = \Drupal::config('webform.settings')->get('assets.css') ?: '';
+    if ($shared_css) {
+      $css[] = $shared_css;
+    }
+    $webform_css = $this->css ?: '';
+    if ($webform_css) {
+      $css[] = $webform_css;
+    }
+    $css += $this->elementsCss;
+
+    // JavaScript.
+    $javascript = [];
+    $shared_javascript = \Drupal::config('webform.settings')->get('assets.javascript') ?: '';
+    if ($shared_javascript) {
+      $javascript[] = $shared_javascript;
+    }
+    $webform_javascript = $this->javascript ?: '';
+    if ($webform_javascript) {
+      $javascript[] = $webform_javascript;
+    }
+    $javascript += $this->elementsJavaScript;
+
+    return [
+      'css' => implode(PHP_EOL, $css),
+      'javascript' => implode(PHP_EOL, $javascript),
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCss() {
+    return $this->css;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setCss($css) {
+    $this->css = $css;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getJavaScript() {
+    return $this->javascript;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setJavaScript($javascript) {
+    $this->javascript = $javascript;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSettings() {
+    // Settings should not be empty even.
+    // https://www.drupal.org/node/2880392.
+    return (isset($this->settings)) ? $this->settings +
+      self::getDefaultSettings() : self::getDefaultSettings();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setSettings(array $settings) {
+    // Always apply the default settings.
+    $this->settings += static::getDefaultSettings();
+
+    // Now apply new settings.
+    foreach ($settings as $name => $value) {
+      if (array_key_exists($name, $this->settings)) {
+        $this->settings[$name] = $value;
+      }
+    }
+
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSetting($key, $default = FALSE) {
+    $settings = $this->getSettings();
+    $value = (isset($settings[$key])) ? $settings[$key] : NULL;
+    if ($default) {
+      return $value ?: \Drupal::config('webform.settings')->get('settings.default_' . $key);
+    }
+    else {
+      return $value;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setSetting($key, $value) {
+    $settings = $this->getSettings();
+    $settings[$key] = $value;
+    $this->setSettings($settings);
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function resetSettings() {
+    $this->settings = $this->settingsOriginal;
+    $this->setOverride(FALSE);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setSettingsOverride(array $settings) {
+    $this->setSettings($settings);
+    $this->setOverride();
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setSettingOverride($key, $value) {
+    $this->setSetting($key, $value);
+    $this->setOverride();
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setPropertyOverride($property_name, $value) {
+    $this->set($property_name, $value);
+    $this->setOverride();
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getAccessRules() {
+    return $this->access;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setAccessRules(array $access) {
+    $this->access = $access;
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getDefaultSettings() {
+    return [
+      'ajax' => FALSE,
+      'ajax_scroll_top' => 'form',
+      'ajax_progress_type' => '',
+      'ajax_effect' => '',
+      'ajax_speed' => NULL,
+      'page' => TRUE,
+      'page_submit_path' => '',
+      'page_confirm_path' => '',
+      'page_admin_theme' => FALSE,
+      'form_title' => 'both',
+      'form_submit_once' => FALSE,
+      'form_exception_message' => '',
+      'form_open_message' => '',
+      'form_close_message' => '',
+      'form_previous_submissions' => TRUE,
+      'form_confidential' => FALSE,
+      'form_confidential_message' => '',
+      'form_remote_addr' => TRUE,
+      'form_convert_anonymous' => FALSE,
+      'form_prepopulate' => FALSE,
+      'form_prepopulate_source_entity' => FALSE,
+      'form_prepopulate_source_entity_required' => FALSE,
+      'form_prepopulate_source_entity_type' => FALSE,
+      'form_reset' => FALSE,
+      'form_disable_autocomplete' => FALSE,
+      'form_novalidate' => FALSE,
+      'form_disable_inline_errors' => FALSE,
+      'form_required' => FALSE,
+      'form_unsaved' => FALSE,
+      'form_disable_back' => FALSE,
+      'form_submit_back' => FALSE,
+      'form_autofocus' => FALSE,
+      'form_details_toggle' => FALSE,
+      'form_access_denied' => WebformInterface::ACCESS_DENIED_DEFAULT,
+      'form_access_denied_title' => '',
+      'form_access_denied_message' => '',
+      'form_access_denied_attributes' => [],
+      'form_file_limit' => '',
+      'submission_label' => '',
+      'submission_log' => FALSE,
+      'submission_views' => [],
+      'submission_views_replace' => [],
+      'submission_user_columns' => [],
+      'submission_user_duplicate' => FALSE,
+      'submission_access_denied' => WebformInterface::ACCESS_DENIED_DEFAULT,
+      'submission_access_denied_title' => '',
+      'submission_access_denied_message' => '',
+      'submission_access_denied_attributes' => [],
+      'submission_exception_message' => '',
+      'submission_locked_message' => '',
+      'submission_excluded_elements' => [],
+      'submission_exclude_empty' => FALSE,
+      'submission_exclude_empty_checkbox' => FALSE,
+      'previous_submission_message' => '',
+      'previous_submissions_message' => '',
+      'autofill' => FALSE,
+      'autofill_message' => '',
+      'autofill_excluded_elements' => [],
+      'wizard_progress_bar' => TRUE,
+      'wizard_progress_pages' => FALSE,
+      'wizard_progress_percentage' => FALSE,
+      'wizard_progress_link' => FALSE,
+      'wizard_progress_states' => FALSE,
+      'wizard_start_label' => '',
+      'wizard_preview_link' => FALSE,
+      'wizard_confirmation' => TRUE,
+      'wizard_confirmation_label' => '',
+      'wizard_track' => '',
+      'preview' => DRUPAL_DISABLED,
+      'preview_label' => '',
+      'preview_title' => '',
+      'preview_message' => '',
+      'preview_attributes' => [],
+      'preview_excluded_elements' => [],
+      'preview_exclude_empty' => TRUE,
+      'preview_exclude_empty_checkbox' => FALSE,
+      'draft' => self::DRAFT_NONE,
+      'draft_multiple' => FALSE,
+      'draft_auto_save' => FALSE,
+      'draft_saved_message' => '',
+      'draft_loaded_message' => '',
+      'draft_pending_single_message' => '',
+      'draft_pending_multiple_message' => '',
+      'confirmation_type' => WebformInterface::CONFIRMATION_PAGE,
+      'confirmation_title' => '',
+      'confirmation_message' => '',
+      'confirmation_url' => '',
+      'confirmation_attributes' => [],
+      'confirmation_back' => TRUE,
+      'confirmation_back_label' => '',
+      'confirmation_back_attributes' => [],
+      'confirmation_exclude_query' => FALSE,
+      'confirmation_exclude_token' => FALSE,
+      'confirmation_update' => FALSE,
+      'limit_total' => NULL,
+      'limit_total_interval' => NULL,
+      'limit_total_message' => '',
+      'limit_total_unique' => FALSE,
+      'limit_user' => NULL,
+      'limit_user_interval' => NULL,
+      'limit_user_message' => '',
+      'limit_user_unique' => FALSE,
+      'entity_limit_total' => NULL,
+      'entity_limit_total_interval' => NULL,
+      'entity_limit_user' => NULL,
+      'entity_limit_user_interval' => NULL,
+      'purge' => WebformSubmissionStorageInterface::PURGE_NONE,
+      'purge_days' => NULL,
+      'results_disabled' => FALSE,
+      'results_disabled_ignore' => FALSE,
+      'results_customize' => FALSE,
+      'token_view' => FALSE,
+      'token_update' => FALSE,
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSubmissionForm(array $values = [], $operation = 'add') {
+    // Test a single webform variant which is set via
+    // ?_webform_handler[ELEMENT_KEY]={variant_id}.
+    $webform_variant = \Drupal::request()->query->get('_webform_variant') ?: [];
+    if ($webform_variant &&
+      ($operation === 'add' && $this->access('update') || $operation === 'test' && $this->access('test'))) {
+      $values += ['data' => []];
+      $values['data'] = $webform_variant + $values['data'];
+    }
+
+    // Set this webform's id which can be used by preCreate hooks.
+    $values['webform_id'] = $this->id();
+
+    /** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
+    $webform_submission = $this->entityTypeManager()
+      ->getStorage('webform_submission')
+      ->create($values);
+
+    // Pass this webform to the webform submission as a direct entity reference.
+    // This guarantees overridden properties and settings are maintained.
+    // Not sure why the overridden webform is not being correctly passed to the
+    // webform submission.
+    // @see \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem::setValue
+    if ($this->isOverridden()) {
+      $webform_submission->webform_id->entity = $this;
+    }
+
+    return \Drupal::service('entity.form_builder')
+      ->getForm($webform_submission, $operation);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementsOriginalRaw() {
+    return $this->elementsOriginal;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementsOriginalDecoded() {
+    $this->elementsOriginal;
+    try {
+      $elements = Yaml::decode($this->elementsOriginal);
+      return (is_array($elements)) ? $elements : [];
+    }
+    catch (\Exception $exception) {
+      return FALSE;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementsRaw() {
+    return $this->elements;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementsDecoded() {
+    $this->initElements();
+    return $this->elementsDecoded;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementsInitialized() {
+    $this->initElements();
+    return $this->elementsInitialized;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementsInitializedAndFlattened($operation = NULL) {
+    $this->initElements();
+    return $this->checkElementsFlattenedAccess($operation, $this->elementsInitializedAndFlattened);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementsDecodedAndFlattened($operation = NULL) {
+    $this->initElements();
+    return $this->checkElementsFlattenedAccess($operation, $this->elementsDecodedAndFlattened);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementsInitializedFlattenedAndHasValue($operation = NULL) {
+    $this->initElements();
+    return $this->checkElementsFlattenedAccess($operation, $this->elementsInitializedFlattenedAndHasValue);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementsManagedFiles() {
+    $this->initElements();
+    return $this->elementsManagedFiles;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementsAttachments() {
+    $this->initElements();
+    return $this->elementsAttachments;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementsComputed() {
+    $this->initElements();
+    return $this->elementsComputed;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementsVariant() {
+    $this->initElements();
+    return $this->elementsVariant;
+  }
+
+  /**
+   * Check operation access for each element.
+   *
+   * @param string $operation
+   *   (optional) The operation that is to be performed on the element.
+   * @param array $elements
+   *   An associative array of flattened form elements.
+   *
+   * @return array
+   *   An associative array of flattened form elements with each element's
+   *   operation access checked.
+   */
+  protected function checkElementsFlattenedAccess($operation = NULL, array $elements) {
+    if ($operation === NULL) {
+      return $elements;
+    }
+
+    /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
+    $element_manager = \Drupal::service('plugin.manager.webform.element');
+    foreach ($elements as $key => $element) {
+      $element_plugin = $element_manager->getElementInstance($element, $this);
+      if (!$element_plugin->checkAccessRules($operation, $element)) {
+        unset($elements[$key]);
+      }
+    }
+    return $elements;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementsSelectorOptions(array $options = []) {
+    /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
+    $element_manager = \Drupal::service('plugin.manager.webform.element');
+
+    // The value element is excluded because it is not available
+    // to the #states API. The value element is available to WebformHandles.
+    // @see \Drupal\webform\Form\WebformHandlerFormBase
+    $options += ['excluded_elements' => ['value']];
+
+    $selectors = [];
+    $elements = $this->getElementsInitializedAndFlattened();
+    foreach ($elements as $element) {
+      $element_plugin = $element_manager->getElementInstance($element, $this);
+
+      // Check excluded elements.
+      if ($options['excluded_elements'] && in_array($element_plugin->getPluginId(), $options['excluded_elements'])) {
+        continue;
+      }
+
+      $element_selectors = $element_plugin->getElementSelectorOptions($element);
+      foreach ($element_selectors as $element_selector_key => $element_selector_value) {
+        // Suffix duplicate selector optgroups with empty characters.
+        //
+        // This prevents elements with the same titles and multiple selectors
+        // from clobbering each other.
+        if (isset($selectors[$element_selector_key]) && is_array($element_selector_value)) {
+          while (isset($selectors[$element_selector_key])) {
+            $element_selector_key .= ' ';
+          }
+          $selectors[$element_selector_key] = $element_selector_value;
+        }
+        else {
+          $selectors[$element_selector_key] = $element_selector_value;
+        }
+      }
+      $selectors += $element_plugin->getElementSelectorOptions($element);
+    }
+    return $selectors;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementsSelectorSourceValues() {
+    /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
+    $element_manager = \Drupal::service('plugin.manager.webform.element');
+
+    $source_values = [];
+    $elements = $this->getElementsInitializedAndFlattened();
+    foreach ($elements as $element) {
+      $element_plugin = $element_manager->getElementInstance($element, $this);
+      $source_values += $element_plugin->getElementSelectorSourceValues($element);
+    }
+    return $source_values;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementsPrepopulate() {
+    $this->initElements();
+    return $this->elementsPrepopulate;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementsDefaultData() {
+    $this->initElements();
+    return $this->elementsDefaultData;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setElements(array $elements) {
+    $this->elements = WebformYaml::encode($elements);
+    $this->resetElements();
+    return $this;
+  }
+
+  /**
+   * Initialize parse webform elements.
+   */
+  protected function initElements() {
+    if (isset($this->elementsInitialized)) {
+      return;
+    }
+
+    // @see \Drupal\webform\Entity\Webform::resetElements
+    $this->hasFlexboxLayout = FALSE;
+    $this->hasContainer = FALSE;
+    $this->hasConditions = FALSE;
+    $this->hasRequired = FALSE;
+    $this->elementsPrepopulate = [];
+    $this->elementsActions = [];
+    $this->elementsWizardPages = [];
+    $this->elementsDecodedAndFlattened = [];
+    $this->elementsInitializedAndFlattened = [];
+    $this->elementsInitializedFlattenedAndHasValue = [];
+    $this->elementsTranslations = [];
+    $this->elementsManagedFiles = [];
+    $this->elementsAttachments = [];
+    $this->elementsComputed = [];
+    $this->elementsVariant = [];
+    $this->elementsCss = [];
+    $this->elementsJavaScript = [];
+    $this->elementsDefaultData = [];
+
+    try {
+      $config_translation = \Drupal::moduleHandler()->moduleExists('config_translation');
+      /** @var \Drupal\webform\WebformTranslationManagerInterface $translation_manager */
+      $translation_manager = \Drupal::service('webform.translation_manager');
+      /** @var \Drupal\Core\Language\LanguageManagerInterface $language_manager */
+      $language_manager = \Drupal::service('language_manager');
+
+      // If current webform is translated, load the base (default) webform and
+      // apply the translation to the elements.
+      if ($config_translation
+        && ($this->langcode != $language_manager->getCurrentLanguage()->getId())) {
+        // Always get the elements in the original language.
+        $elements = $translation_manager->getElements($this);
+        // For none admin routes get the element (label) translations.
+        if (!$translation_manager->isAdminRoute()) {
+          $this->elementsTranslations = $translation_manager->getElements($this, $language_manager->getCurrentLanguage()->getId());
+        }
+      }
+      else {
+        $elements = Yaml::decode($this->elements);
+      }
+
+      // Since YAML supports simple values.
+      $elements = (is_array($elements)) ? $elements : [];
+      $this->elementsDecoded = $elements;
+    }
+    catch (\Exception $exception) {
+      $link = $this->toLink($this->t('Edit'), 'edit-form')->toString();
+      \Drupal::logger('webform')
+        ->notice('%title elements are not valid. @message', [
+          '%title' => $this->label(),
+          '@message' => $exception->getMessage(),
+          'link' => $link,
+        ]);
+      $elements = FALSE;
+    }
+
+    if ($elements !== FALSE) {
+      $this->initElementsRecursive($elements);
+      $this->invokeHandlers('alterElements', $elements, $this);
+    }
+
+    $this->elementsInitialized = $elements;
+  }
+
+  /**
+   * Reset parsed and cached webform elements.
+   */
+  protected function resetElements() {
+    $this->pages = NULL;
+    $this->hasFlexboxLayout = NULL;
+    $this->hasContainer = NULL;
+    $this->hasConditions = NULL;
+    $this->hasRequired = NULL;
+    $this->elementsPrepopulate = [];
+    $this->elementsActions = [];
+    $this->elementsWizardPages = [];
+    $this->elementsDecoded = NULL;
+    $this->elementsInitialized = NULL;
+    $this->elementsDecodedAndFlattened = NULL;
+    $this->elementsInitializedAndFlattened = NULL;
+    $this->elementsInitializedFlattenedAndHasValue = NULL;
+    $this->elementsTranslations = NULL;
+    $this->elementsManagedFiles = [];
+    $this->elementsAttachments = [];
+    $this->elementsComputed = [];
+    $this->elementsVariant = [];
+    $this->elementsCss = [];
+    $this->elementsJavaScript = [];
+    $this->elementsDefaultData = [];
+  }
+
+  /**
+   * Initialize webform elements into a flatten array.
+   *
+   * @param array $elements
+   *   The webform elements.
+   * @param string $parent
+   *   The parent key.
+   * @param int $depth
+   *   The element's depth.
+   */
+  protected function initElementsRecursive(array &$elements, $parent = '', $depth = 0) {
+    /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
+    $element_manager = \Drupal::service('plugin.manager.webform.element');
+
+    // Remove ignored properties.
+    $elements = WebformElementHelper::removeIgnoredProperties($elements);
+
+    foreach ($elements as $key => &$element) {
+      if (!WebformElementHelper::isElement($element, $key)) {
+        continue;
+      }
+
+      // Apply translation to element.
+      if (isset($this->elementsTranslations[$key])) {
+        WebformElementHelper::applyTranslation($element, $this->elementsTranslations[$key]);
+      }
+
+      // Prevent regressions where webform_computed_* element is still using
+      // #value instead of #template.
+      if (isset($element['#type']) && strpos($element['#type'], 'webform_computed_') === 0) {
+        if (isset($element['#value']) && !isset($element['#template'])) {
+          $element['#template'] = $element['#value'];
+          unset($element['#value']);
+        }
+      }
+
+      // Copy only the element properties to decoded and flattened elements.
+      $this->elementsDecodedAndFlattened[$key] = WebformElementHelper::getProperties($element);
+
+      // Set webform, id, key, parent_key, depth, and parent children.
+      $element['#webform'] = $this->id();
+      $element['#webform_id'] = $this->id() . '--' . $key;
+      $element['#webform_key'] = $key;
+      $element['#webform_parent_key'] = $parent;
+      $element['#webform_parent_flexbox'] = FALSE;
+      $element['#webform_depth'] = $depth;
+      $element['#webform_children'] = [];
+      $element['#webform_multiple'] = FALSE;
+      $element['#webform_composite'] = FALSE;
+
+      if (!empty($parent)) {
+        $parent_element =& $this->elementsInitializedAndFlattened[$parent];
+        // Add element to the parent element's children.
+        $parent_element['#webform_children'][$key] = $key;
+        // Set #parent_flexbox to TRUE is the parent element is a
+        // 'webform_flexbox'.
+        $element['#webform_parent_flexbox'] = (isset($parent_element['#type']) && $parent_element['#type'] == 'webform_flexbox') ? TRUE : FALSE;
+
+        $element['#webform_parents'] = $parent_element['#webform_parents'];
+      }
+
+      // Add element key to parents.
+      // #webform_parents allows make it possible to use NestedArray::getValue
+      // to get the entire unflattened element.
+      $element['#webform_parents'][] = $key;
+
+      // Set #title and #admin_title to NULL if it is not defined.
+      $element += [
+        '#title' => NULL,
+        '#admin_title' => NULL,
+      ];
+
+      // Set #markup type to 'webform_markup' to trigger #display_on behavior.
+      // @see https://www.drupal.org/node/2036237
+      if (empty($element['#type']) && empty($element['#theme']) && isset($element['#markup'])) {
+        $element['#type'] = 'webform_markup';
+      }
+
+      $element_plugin = NULL;
+      if (isset($element['#type'])) {
+        // Load the element's handler.
+        $element_plugin = $element_manager->getElementInstance($element, $this);
+
+        // Store a reference to the plugin id which is used by derivatives.
+        // Webform elements support derivatives but Form API elements
+        // do not support derivatives. Therefore we need to store a
+        // reference to the plugin id for when a webform element derivative
+        // changes the $elements['#type'] property.
+        // @see \Drupal\webform\Plugin\WebformElementManager::getElementPluginId
+        // @see \Drupal\webform_options_custom\Plugin\WebformElement\WebformOptionsCustom::setOptions
+        $element['#webform_plugin_id'] = $element_plugin->getPluginId();
+
+        // Initialize the element.
+        // Note: Composite sub elements are initialized via
+        // \Drupal\webform\Plugin\WebformElement\WebformCompositeBase::initialize
+        // and stored in the '#webform_composite_elements' property.
+        $element_plugin->initialize($element);
+
+        // Track flexbox.
+        if ($element['#type'] == 'flexbox' || $element['#type'] == 'webform_flexbox') {
+          $this->hasFlexboxLayout = TRUE;
+        }
+
+        // Track container.
+        if ($element_plugin->isContainer($element)) {
+          $this->hasContainer = TRUE;
+        }
+
+        // Track conditional.
+        if (!empty($element['#states'])) {
+          $this->hasConditions = TRUE;
+        }
+
+        // Track required.
+        if (!empty($element['#required']) || (!empty($element['#states']) && (!empty($element['#states']['required']) || !empty($element['#states']['optional'])))) {
+          $this->hasRequired = TRUE;
+        }
+
+        // Track prepopulated.
+        if (!empty($element['#prepopulate']) && $element_plugin->hasProperty('prepopulate')) {
+          $this->elementsPrepopulate[$key] = $key;
+        }
+
+        // Track actions.
+        if ($element_plugin instanceof WebformActions) {
+          $this->elementsActions[$key] = $key;
+        }
+
+        // Track wizard.
+        if ($element_plugin instanceof WebformWizardPage) {
+          $this->elementsWizardPages[$key] = $key;
+        }
+
+        // Track managed files.
+        if ($element_plugin->hasManagedFiles($element)) {
+          $this->elementsManagedFiles[$key] = $key;
+        }
+
+        // Track attachments.
+        if ($element_plugin instanceof WebformElementAttachmentInterface) {
+          $this->elementsAttachments[$key] = $key;
+        }
+
+        // Track computed.
+        if ($element_plugin instanceof WebformElementComputedInterface) {
+          $this->elementsComputed[$key] = $key;
+        }
+
+        // Track variant.
+        if ($element_plugin instanceof WebformElementVariantInterface) {
+          $this->elementsVariant[$key] = $key;
+        }
+
+        // Track assets (CSS and JavaScript).
+        // @see \Drupal\webform_options_custom\Plugin\WebformElement\WebformOptionsCustom
+        if ($element_plugin instanceof WebformElementAssetInterface) {
+          $asset_id = $element_plugin->getAssetId();
+          if (!isset($this->elementsCss[$asset_id])) {
+            if ($css = $element_plugin->getCss()) {
+              $this->elementsCss[$asset_id] = $css;
+            }
+          }
+          if (!isset($this->elementsJavaScript[$asset_id])) {
+            if ($javascript = $element_plugin->getJavaScript()) {
+              $this->elementsJavaScript[$asset_id] = $javascript;
+            }
+          }
+        }
+
+        // Track default data.
+        if (isset($element['#value'])) {
+          $this->elementsDefaultData[$key] = $element['#value'];
+        }
+        elseif (isset($element['#default_value'])) {
+          $this->elementsDefaultData[$key] = $element['#default_value'];
+        }
+
+        $element['#webform_multiple'] = $element_plugin->hasMultipleValues($element);
+        $element['#webform_composite'] = $element_plugin->isComposite();
+      }
+
+      // Copy only the element properties to initialized and flattened elements.
+      $this->elementsInitializedAndFlattened[$key] = WebformElementHelper::getProperties($element);
+
+      // Check if element has value (aka can be exported) and add it to
+      // flattened has value array.
+      if ($element_plugin && $element_plugin->isInput($element)) {
+        $this->elementsInitializedFlattenedAndHasValue[$key] = &$this->elementsInitializedAndFlattened[$key];
+      }
+
+      $this->initElementsRecursive($element, $key, $depth + 1);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElement($key, $include_children = FALSE) {
+    $elements_flattened = $this->getElementsInitializedAndFlattened();
+    $element = (isset($elements_flattened[$key])) ? $elements_flattened[$key] : NULL;
+    if ($element && $include_children) {
+      $elements = $this->getElementsInitialized();
+      return NestedArray::getValue($elements, $element['#webform_parents']);
+    }
+    else {
+      return $element;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementDecoded($key) {
+    $elements = $this->getElementsDecodedAndFlattened();
+    return (isset($elements[$key])) ? $elements[$key] : NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementInitialized($key) {
+    $elements = $this->getElementsInitializedAndFlattened();
+    return (isset($elements[$key])) ? $elements[$key] : NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setElementProperties($key, array $properties, $parent_key = '') {
+    $elements = $this->getElementsDecoded();
+    // If element is was not added to elements, add it as the last element.
+    if (!$this->setElementPropertiesRecursive($elements, $key, $properties, $parent_key)) {
+      if ($this->hasActions() && array_key_exists(end($this->elementsActions), $elements)) {
+        // Add element before the last 'webform_actions' element if action is
+        // not placed into container.
+        $last_action_key = end($this->elementsActions);
+        $updated_elements = [];
+        foreach ($elements as $element_key => $element) {
+          if ($element_key == $last_action_key) {
+            $updated_elements[$key] = $properties;
+          }
+          $updated_elements[$element_key] = $element;
+        }
+        $elements = $updated_elements;
+      }
+      else {
+        $elements[$key] = $properties;
+      }
+    }
+    $this->setElements($elements);
+    return $this;
+  }
+
+  /**
+   * Set element properties.
+   *
+   * @param array $elements
+   *   An associative nested array of elements.
+   * @param string $key
+   *   The element's key.
+   * @param array $properties
+   *   An associative array of properties.
+   * @param string $parent_key
+   *   (optional) The element's parent key. Only used for new elements.
+   *
+   * @return bool
+   *   TRUE when the element's properties has been set. FALSE when the element
+   *   has not been found.
+   */
+  protected function setElementPropertiesRecursive(array &$elements, $key, array $properties, $parent_key = '') {
+    foreach ($elements as $element_key => &$element) {
+      if (!WebformElementHelper::isElement($element, $element_key)) {
+        continue;
+      }
+
+      if ($element_key == $key) {
+        $element = $properties + WebformElementHelper::removeProperties($element);
+        return TRUE;
+      }
+
+      if ($element_key == $parent_key) {
+        $element[$key] = $properties;
+        return TRUE;
+      }
+
+      if ($this->setElementPropertiesRecursive($element, $key, $properties, $parent_key)) {
+        return TRUE;
+      }
+    }
+
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteElement($key) {
+    $element = $this->getElementDecoded($key);
+
+    // Delete element from the elements render array.
+    $elements = $this->getElementsDecoded();
+    $sub_element_keys = $this->deleteElementRecursive($elements, $key);
+    $this->setElements($elements);
+
+    // Delete the variants.
+    $is_variant = (isset($element['#type']) && $element['#type'] === 'webform_variant');
+    if ($is_variant) {
+      $variants = $this->getVariants(NULL, NULL, $key);
+      foreach ($variants as $variant) {
+        $this->deleteWebformVariant($variant);
+      }
+    }
+
+    // Delete submission element key data.
+    \Drupal::database()->delete('webform_submission_data')
+      ->condition('webform_id', $this->id())
+      ->condition('name', $sub_element_keys, 'IN')
+      ->execute();
+  }
+
+  /**
+   * Remove an element by key from a render array.
+   *
+   * @param array $elements
+   *   An associative nested array of elements.
+   * @param string $key
+   *   The element's key.
+   *
+   * @return bool|array
+   *   An array containing the deleted element and sub element keys.
+   *   FALSE is no sub elements are found.
+   */
+  protected function deleteElementRecursive(array &$elements, $key) {
+    foreach ($elements as $element_key => &$element) {
+      if (!WebformElementHelper::isElement($element, $element_key)) {
+        continue;
+      }
+
+      if ($element_key == $key) {
+        $sub_element_keys = [$element_key => $element_key];
+        $this->collectSubElementKeysRecursive($sub_element_keys, $element);
+        unset($elements[$element_key]);
+        return $sub_element_keys;
+      }
+
+      if ($sub_element_keys = $this->deleteElementRecursive($element, $key)) {
+        return $sub_element_keys;
+      }
+    }
+
+    return FALSE;
+  }
+
+  /**
+   * Collect sub element keys from a render array.
+   *
+   * @param array $sub_element_keys
+   *   An array to be populated with sub element keys.
+   * @param array $elements
+   *   A render array.
+   */
+  protected function collectSubElementKeysRecursive(array &$sub_element_keys, array $elements) {
+    foreach ($elements as $key => &$element) {
+      if (!WebformElementHelper::isElement($element, $key)) {
+        continue;
+      }
+      $sub_element_keys[$key] = $key;
+      $this->collectSubElementKeysRecursive($sub_element_keys, $element);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPages($operation = 'default', WebformSubmissionInterface $webform_submission = NULL) {
+    $pages = $this->buildPages($operation);
+    if ($this->getSetting('wizard_progress_states') && $webform_submission) {
+      /** @var \Drupal\webform\WebformSubmissionConditionsValidatorInterface $constraint_validator */
+      $constraint_validator = \Drupal::service('webform_submission.conditions_validator');
+      $pages = $constraint_validator->buildPages($pages, $webform_submission);
+    }
+    return $pages;
+  }
+
+  /**
+   * Build and cache a webform's wizard pages based on the current operation.
+   *
+   * @param string $operation
+   *   The webform submission operation.
+   *   Usually 'default', 'add', 'edit', 'edit_all', 'api', or 'test'.
+   *
+   * @return array
+   *   An associative array of webform wizard pages.
+   */
+  protected function buildPages($operation = 'default') {
+    if (isset($this->pages[$operation])) {
+      return $this->pages[$operation];
+    }
+
+    /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
+    $element_manager = \Drupal::service('plugin.manager.webform.element');
+
+    $wizard_properties = [
+      '#title' => '#title',
+      '#prev_button_label' => '#prev_button_label',
+      '#next_button_label' => '#next_button_label',
+      '#states' => '#states',
+    ];
+
+    $pages = [];
+
+    // Add webform wizard pages.
+    $elements = $this->getElementsInitialized();
+    if (is_array($elements) && !in_array($operation, ['edit_all', 'api'])) {
+      foreach ($elements as $key => $element) {
+        if (!isset($element['#type'])) {
+          continue;
+        }
+
+        /** @var \Drupal\webform\Plugin\WebformElementInterface $element_plugin */
+        $element_plugin = $element_manager->getElementInstance($element, $this);
+        if (!($element_plugin instanceof WebformElementWizardPageInterface)) {
+          continue;
+        }
+
+        // Check element access rules and only include pages that are visible
+        // to the current user.
+        $access_operation = (in_array($operation, ['default', 'add'])) ? 'create' : 'update';
+        if ($element_plugin->checkAccessRules($access_operation, $element)) {
+          $pages[$key] = array_intersect_key($element, $wizard_properties);
+          $pages[$key]['#access'] = TRUE;
+        }
+      }
+    }
+
+    // Add preview page.
+    $settings = $this->getSettings();
+    if ($settings['preview'] != DRUPAL_DISABLED) {
+      // If there is no start page, we must define one.
+      if (empty($pages)) {
+        $pages['webform_start'] = [
+          '#title' => $this->getSetting('wizard_start_label', TRUE),
+          '#access' => TRUE,
+        ];
+      }
+      $pages['webform_preview'] = [
+        '#title' => $this->getSetting('preview_label', TRUE),
+        '#access' => TRUE,
+      ];
+    }
+
+    // Only add complete page, if there are some pages.
+    if ($pages && $this->getSetting('wizard_confirmation')) {
+      $pages['webform_confirmation'] = [
+        '#title' => $this->getSetting('wizard_confirmation_label', TRUE),
+        '#access' => TRUE,
+      ];
+    }
+
+    $this->pages[$operation] = $pages;
+
+    return $this->pages[$operation];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPage($operation, $key) {
+    $pages = $this->getPages($operation);
+    return (isset($pages[$key])) ? $pages[$key] : NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createDuplicate() {
+    /** @var \Drupal\webform\WebformInterface $duplicate */
+    $duplicate = parent::createDuplicate();
+
+    // Clear path aliases, which must be unique.
+    $duplicate->setSetting('page_submit_path', '');
+    $duplicate->setSetting('page_confirm_path', '');
+
+    // Update owner to current user.
+    $duplicate->setOwnerId(\Drupal::currentUser()->id());
+
+    // If template being used to create a new webform, clear description
+    // and remove the template flag.
+    // @see \Drupal\webform_templates\Controller\WebformTemplatesController::index
+    $is_template_duplicate = \Drupal::request()->get('template');
+    if ($duplicate->isTemplate() && !$is_template_duplicate) {
+      $duplicate->set('description', '');
+      $duplicate->set('template', FALSE);
+    }
+
+    // If archived, remove archive flag.
+    if ($duplicate->isArchived()) {
+      $duplicate->set('archive', FALSE);
+    }
+
+    // Set default status.
+    $duplicate->setStatus(\Drupal::config('webform.settings')->get('settings.default_status'));
+
+    // Remove enforce module dependency when a sub-module's webform is
+    // duplicated.
+    if (isset($duplicate->dependencies['enforced']['module'])) {
+      $modules = WebformReflectionHelper::getSubModules();
+      $duplicate->dependencies['enforced']['module'] = array_diff($duplicate->dependencies['enforced']['module'], $modules);
+      if (empty($duplicate->dependencies['enforced']['module'])) {
+        unset($duplicate->dependencies['enforced']['module']);
+        if (empty($duplicate->dependencies['enforced'])) {
+          unset($duplicate->dependencies['enforced']);
+        }
+      }
+    }
+
+    return $duplicate;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function preCreate(EntityStorageInterface $storage, array &$values) {
+    /** @var \Drupal\webform\WebformAccessRulesManagerInterface $access_rules_manager */
+    $access_rules_manager = \Drupal::service('webform.access_rules_manager');
+
+    $values += [
+      'status' => \Drupal::config('webform.settings')->get('settings.default_status'),
+      'uid' => \Drupal::currentUser()->id(),
+      'settings' => static::getDefaultSettings(),
+      'access' => $access_rules_manager->getDefaultAccessRules(),
+    ];
+
+    // Convert boolean status to STATUS constant.
+    if ($values['status'] === TRUE) {
+      $values['status'] = WebformInterface::STATUS_OPEN;
+    }
+    elseif ($values['status'] === FALSE) {
+      $values['status'] = WebformInterface::STATUS_CLOSED;
+    }
+    elseif ($values['status'] === NULL) {
+      $values['status'] = WebformInterface::STATUS_SCHEDULED;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function postLoad(EntityStorageInterface $storage, array &$entities) {
+    foreach ($entities as $entity) {
+      $entity->elementsOriginal = $entity->elements;
+      $entity->settingsOriginal = $entity->settings;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function preDelete(EntityStorageInterface $storage, array $entities) {
+    /** @var \Drupal\webform\WebformInterface[] $entities */
+    parent::preDelete($storage, $entities);
+
+    /** @var \Drupal\user\UserDataInterface $user_data */
+    $user_data = \Drupal::service('user.data');
+
+    // Delete all paths, states, and user data associated with this webform.
+    foreach ($entities as $entity) {
+      // Delete all paths.
+      $entity->deletePaths();
+
+      // Delete the state.
+      // @see \Drupal\webform\Entity\Webform::getState
+      \Drupal::state()->delete('webform.webform.' . $entity->id());
+
+      // Delete user data.
+      // @see \Drupal\webform\Entity\Webform::getUserData
+      $user_data->delete('webform', NULL, $entity->id());
+    }
+
+    // Delete all submission associated with this webform.
+    $submission_ids = \Drupal::entityQuery('webform_submission')
+      ->accessCheck(FALSE)
+      ->condition('webform_id', array_keys($entities), 'IN')
+      ->sort('sid')
+      ->execute();
+    $submission_storage = \Drupal::entityTypeManager()->getStorage('webform_submission');
+    $submissions = $submission_storage->loadMultiple($submission_ids);
+    $submission_storage->delete($submissions);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheTags() {
+    $cache_tags = parent::getCacheTags();
+    // Add webform to cache tags which are used by the WebformSubmissionForm.
+    $cache_tags[] = 'webform:' . $this->id();
+    // Add webform settings to cache tags which are used to define
+    // default settings.
+    $cache_tags[] = 'config:webform.settings';
+    return $cache_tags;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheContexts() {
+    $cache_contexts = parent::getCacheContexts();
+
+    // Add paths to cache contexts since webform can be placed on multiple
+    // pages.
+    $cache_contexts[] = 'url.path';
+
+    // Add all prepopulate query string parameters.
+    if ($this->getSetting('form_prepopulate')) {
+      $cache_contexts[] = 'url.query_args';
+    }
+    else {
+      // Add source entity type and id query string parameters.
+      if ($this->getSetting('form_prepopulate_source_entity')) {
+        $cache_contexts[] = 'url.query_args:entity_type';
+        $cache_contexts[] = 'url.query_args:entity_id';
+      }
+      // Add webform (secure) token query string parameter.
+      if ($this->getSetting('token_view') || $this->getSetting('token_update')) {
+        $cache_contexts[] = 'url.query_args:token';
+      }
+    }
+
+    return $cache_contexts;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheMaxAge() {
+    if ($this->isScheduled()) {
+      $time = time();
+      if ($this->open && strtotime($this->open) > $time) {
+        return (strtotime($this->open) - $time);
+      }
+      elseif ($this->close && strtotime($this->close) > $time) {
+        return (strtotime($this->close) - $time);
+      }
+    }
+
+    return parent::getCacheMaxAge();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function preSave(EntityStorageInterface $storage) {
+    // Throw exception when saving overridden webform.
+    if ($this->isOverridden()) {
+      throw new WebformException(sprintf('The %s webform [%s] has overridden settings and/or properties and can not be saved.', $this->label(), $this->id()));
+    }
+
+    // Always unpublish templates.
+    if ($this->isTemplate()) {
+      $this->setStatus(WebformInterface::STATUS_CLOSED);
+    }
+
+    // Serialize elements array to YAML.
+    if (is_array($this->elements)) {
+      $this->elements = Yaml::encode($this->elements);
+    }
+
+    parent::preSave($storage);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function postSave(EntityStorageInterface $storage, $update = TRUE) {
+    parent::postSave($storage, $update);
+
+    // Update paths.
+    $this->updatePaths();
+
+    // Invoke handler element CRUD methods.
+    // Note: Comparing parsed YAML since the actual YAML formatting could be
+    // different.
+    $elements_original = $this->getElementsOriginalDecoded() ?: [];
+    $elements = $this->getElementsDecoded() ?: [];
+    if ($elements_original != $elements) {
+      $elements_original = WebformElementHelper::getFlattened($elements_original);
+      $elements = WebformElementHelper::getFlattened($elements);
+
+      // Handle create element.
+      $created_elements = array_diff_key($elements, $elements_original) ?: [];
+      foreach ($created_elements as $element_key => $element) {
+        $this->invokeHandlers('createElement', $element_key, $element);
+      }
+
+      // Handle delete element.
+      $deleted_elements = array_diff_key($elements_original, $elements) ?: [];
+      foreach ($deleted_elements as $element_key => $element) {
+        $this->invokeHandlers('deleteElement', $element_key, $element);
+      }
+
+      // Handle update element.
+      foreach ($elements as $element_key => $element) {
+        if (isset($elements_original[$element_key]) && $elements_original[$element_key] != $element) {
+          $this->invokeHandlers('updateElement', $element_key, $element, $elements_original[$element_key]);
+        }
+      }
+
+      // Invalidate library_info cache tag if any updated or deleted elements
+      // has assets (CSS or JavaScript).
+      // @see webform_library_info_build()
+      /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
+      $element_manager = \Drupal::service('plugin.manager.webform.element');
+      $checked_elements = $created_elements + $deleted_elements;
+      foreach ($checked_elements as $element_key => $element) {
+        $element_plugin = $element_manager->getElementInstance($element, $this);
+        if ($element_plugin instanceof WebformElementAssetInterface
+          && $element_plugin->hasAssets()) {
+          Cache::invalidateTags(['library_info']);
+          break;
+        }
+      }
+    }
+
+    // Reset elements.
+    $this->resetElements();
+    $this->elementsOriginal = $this->elements;
+
+    // Reset settings.
+    $this->settingsOriginal = $this->settings;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function updatePaths() {
+    // Path module must be enabled for URL aliases to be updated.
+    if (!\Drupal::moduleHandler()->moduleExists('path')) {
+      return;
+    }
+
+    // If 'Allow users to post submission from a dedicated URL' is disabled,
+    // delete all existing paths.
+    if (empty($this->settings['page'])) {
+      $this->deletePaths();
+      return;
+    }
+
+    $page_submit_path = trim($this->settings['page_submit_path'], '/');
+    $default_page_base_path = trim(\Drupal::config('webform.settings')->get('settings.default_page_base_path'), '/');
+
+    // Skip generating paths if submit path and base path are empty.
+    if (empty($page_submit_path) && empty($default_page_base_path)) {
+      return;
+    }
+
+    // Update webform base, confirmation, submissions and drafts paths.
+    $path_base_alias = '/' . ($page_submit_path ?: $default_page_base_path . '/' . str_replace('_', '-', $this->id()));
+    $path_suffixes = ['', '/confirmation', '/submissions', '/drafts'];
+    foreach ($path_suffixes as $path_suffix) {
+      $path_source = '/webform/' . $this->id() . $path_suffix;
+      $path_alias = $path_base_alias . $path_suffix;
+      if ($path_suffix === '/confirmation' && $this->settings['page_confirm_path']) {
+        $path_alias = '/' . trim($this->settings['page_confirm_path'], '/');
+      }
+      $this->updatePath($path_source, $path_alias, $this->langcode);
+      $this->updatePath($path_source, $path_alias, LanguageInterface::LANGCODE_NOT_SPECIFIED);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deletePaths() {
+    // Path module must be enabled for URL aliases to be updated.
+    if (!\Drupal::moduleHandler()->moduleExists('path')) {
+      return;
+    }
+
+    /** @var \Drupal\Core\Path\AliasStorageInterface $path_alias_storage */
+    $path_alias_storage = \Drupal::service('path.alias_storage');
+
+    // Delete webform base, confirmation, submissions and drafts paths.
+    $path_suffixes = ['', '/confirmation', '/submissions', '/drafts'];
+    foreach ($path_suffixes as $path_suffix) {
+      $path_alias_storage->delete(['source' => '/webform/' . $this->id() . $path_suffix]);
+    }
+  }
+
+  /**
+   * Saves a path alias to the database.
+   *
+   * @param string $source
+   *   The internal system path.
+   * @param string $alias
+   *   The URL alias.
+   * @param string $langcode
+   *   (optional) The language code of the alias.
+   */
+  protected function updatePath($source, $alias, $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED) {
+    /** @var \Drupal\Core\Path\AliasStorageInterface $path_alias_storage */
+    $path_alias_storage = \Drupal::service('path.alias_storage');
+
+    $path = $path_alias_storage->load(['source' => $source, 'langcode' => $langcode]);
+
+    // Check if the path alias is already setup.
+    if ($path && ($path['alias'] == $alias)) {
+      return;
+    }
+
+    $pid = $path['pid'] ?? NULL;
+    $path_alias_storage->save($source, $alias, $langcode, $pid);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPluginCollections() {
+    return [
+      'handlers' => $this->getHandlers(),
+      'variants' => $this->getVariants(),
+    ];
+  }
+
+  /****************************************************************************/
+  // Handler plugins.
+  /****************************************************************************/
+
+  /**
+   * Returns the webform handler plugin manager.
+   *
+   * @return \Drupal\Component\Plugin\PluginManagerInterface
+   *   The webform handler plugin manager.
+   */
+  protected function getWebformHandlerPluginManager() {
+    return \Drupal::service('plugin.manager.webform.handler');
+  }
+
+  /**
+   * Reset cached handler settings.
+   */
+  protected function resetHandlers() {
+    $this->hasMessageHandler = NULL;
+    $this->hasAnonymousSubmissionTrackingHandler = NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasMessageHandler() {
+    if (isset($this->hasMessagehandler)) {
+      $this->hasMessagehandler;
+    }
+
+    $this->hasMessagehandler = FALSE;
+    $handlers = $this->getHandlers();
+    foreach ($handlers as $handler) {
+      if ($handler instanceof WebformHandlerMessageInterface) {
+        $this->hasMessagehandler = TRUE;
+        break;
+      }
+    }
+
+    return $this->hasMessagehandler;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasAnonymousSubmissionTrackingHandler() {
+    if (isset($this->hasAnonymousSubmissionTrackingHandler)) {
+      $this->hasAnonymousSubmissionTrackingHandler;
+    }
+
+    $this->hasAnonymousSubmissionTrackingHandler = FALSE;
+    $handlers = $this->getHandlers();
+    foreach ($handlers as $handler) {
+      if ($handler->hasAnonymousSubmissionTracking()) {
+        $this->hasAnonymousSubmissionTrackingHandler = TRUE;
+        break;
+      }
+    }
+
+    return $this->hasAnonymousSubmissionTrackingHandler;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getHandler($handler_id) {
+    return $this->getHandlers()->get($handler_id);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getHandlers($plugin_id = NULL, $status = NULL, $results = NULL, $submission = NULL) {
+    if (!$this->handlersCollection) {
+      $this->handlersCollection = new WebformHandlerPluginCollection($this->getWebformHandlerPluginManager(), $this->handlers);
+      /** @var \Drupal\webform\Plugin\WebformHandlerBase $handler */
+      foreach ($this->handlersCollection as $handler) {
+        // Initialize the handler and pass in the webform.
+        $handler->setWebform($this);
+      }
+      $this->handlersCollection->sort();
+    }
+
+    /** @var \Drupal\webform\Plugin\WebformHandlerPluginCollection $handlers */
+    $handlers = $this->handlersCollection;
+
+    // Clone the handlers if they are being filtered.
+    if (isset($plugin_id) || isset($status) || isset($results)) {
+      /** @var \Drupal\webform\Plugin\WebformHandlerPluginCollection $handlers */
+      $handlers = clone $this->handlersCollection;
+    }
+
+    // Filter the handlers by plugin id.
+    // This is used to limit track and enforce a handlers cardinality.
+    if (isset($plugin_id)) {
+      foreach ($handlers as $instance_id => $handler) {
+        if ($handler->getPluginId() != $plugin_id) {
+          $handlers->removeInstanceId($instance_id);
+        }
+      }
+    }
+
+    // Filter the handlers by status.
+    // This is used to limit track and enforce a handlers cardinality.
+    if (isset($status)) {
+      foreach ($handlers as $instance_id => $handler) {
+        if ($handler->getStatus() != $status) {
+          $handlers->removeInstanceId($instance_id);
+        }
+      }
+    }
+
+    // Filter the handlers by results.
+    // This is used to track is results are processed or ignored.
+    if (isset($results)) {
+      foreach ($handlers as $instance_id => $handler) {
+        $plugin_definition = $handler->getPluginDefinition();
+        if ($plugin_definition['results'] != $results) {
+          $handlers->removeInstanceId($instance_id);
+        }
+      }
+    }
+
+    // Filter the handlers by submission.
+    // This is used to track is submissions must be saved to the database.
+    if (isset($submission)) {
+      foreach ($handlers as $instance_id => $handler) {
+        $plugin_definition = $handler->getPluginDefinition();
+        if ($plugin_definition['submission'] != $submission) {
+          $handlers->removeInstanceId($instance_id);
+        }
+      }
+    }
+
+    return $handlers;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addWebformHandler(WebformHandlerInterface $handler) {
+    $handler->setWebform($this);
+    $handler_id = $handler->getHandlerId();
+    $configuration = $handler->getConfiguration();
+    $this->getHandlers()->addInstanceId($handler_id, $configuration);
+    $this->save();
+    $this->resetHandlers();
+    $handler->createHandler();
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function updateWebformHandler(WebformHandlerInterface $handler) {
+    $handler->setWebform($this);
+    $handler_id = $handler->getHandlerId();
+    $configuration = $handler->getConfiguration();
+    $this->getHandlers()->setInstanceConfiguration($handler_id, $configuration);
+    $this->save();
+    $this->resetHandlers();
+    $handler->updateHandler();
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteWebformHandler(WebformHandlerInterface $handler) {
+    $handler->setWebform($this);
+    $this->getHandlers()->removeInstanceId($handler->getHandlerId());
+    $handler->deleteHandler();
+    $this->save();
+    $this->resetHandlers();
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function invokeHandlers($method, &$data, &$context1 = NULL, &$context2 = NULL, &$context3 = NULL) {
+    // Get webform submission from arguments for conditions validations.
+    $webform_submission = NULL;
+    $args = func_get_args();
+    foreach ($args as $arg) {
+      if ($arg instanceof WebformSubmissionInterface) {
+        $webform_submission = $arg;
+        break;
+      }
+    }
+
+    // Get handlers.
+    $handlers = $this->getHandlers();
+
+    switch ($method) {
+      case 'overrideSettings';
+        // If webform submission and alter settings, make sure to completely
+        // reset all settings to their original values.
+        $this->resetSettings();
+        $settings = $this->getSettings();
+        foreach ($handlers as $handler) {
+          $handler->setWebformSubmission($webform_submission);
+          $this->invokeHandlerAlter($handler, $method, $args);
+          if ($this->isHandlerEnabled($handler, $webform_submission)) {
+            $handler->overrideSettings($settings, $webform_submission);
+          }
+        }
+        // If a handler has change some settings set override.
+        // Only look for altered original settings, which prevents issues where
+        // a webform saved settings and default settings are out-of-sync.
+        if (array_intersect_key($settings, $this->settingsOriginal) != $this->settingsOriginal) {
+          $this->setSettingsOverride($settings);
+        }
+        return NULL;
+
+      case 'access':
+      case 'accessElement':
+        // WebformHandler::access() and WebformHandler::accessElement()
+        // returns a AccessResult.
+        /** @var \Drupal\Core\Access\AccessResultInterface $result */
+        $result = AccessResult::neutral();
+        foreach ($handlers as $handler) {
+          $handler->setWebformSubmission($webform_submission);
+          $this->invokeHandlerAlter($handler, $method, $args);
+          if ($this->isHandlerEnabled($handler, $webform_submission)) {
+            $result = $result->orIf($handler->$method($data, $context1, $context2));
+          }
+        }
+        return $result;
+
+      default:
+        foreach ($handlers as $handler) {
+          $handler->setWebformSubmission($webform_submission);
+          $this->invokeHandlerAlter($handler, $method, $args);
+          if ($this->isHandlerEnabled($handler, $webform_submission)) {
+            $handler->$method($data, $context1, $context2);
+          }
+        }
+        return NULL;
+    }
+  }
+
+  /**
+   * Determine if a webform handler is enabled.
+   *
+   * @param \Drupal\webform\Plugin\WebformHandlerInterface $handler
+   *   A webform handler.
+   * @param \Drupal\webform\WebformSubmissionInterface|null $webform_submission
+   *   A webform submission.
+   *
+   * @return bool
+   *   TRUE if a webform handler is enabled.
+   */
+  protected function isHandlerEnabled(WebformHandlerInterface $handler, WebformSubmissionInterface $webform_submission = NULL) {
+    // Check if the handler is disabled.
+    if ($handler->isDisabled()) {
+      return FALSE;
+    }
+    // If webform submission defined, check the handlers conditions.
+    elseif ($webform_submission && !$handler->checkConditions($webform_submission)) {
+      return FALSE;
+    }
+    else {
+      return TRUE;
+    }
+  }
+
+  /**
+   * Alter a webform handler when it is invoked.
+   *
+   * @param \Drupal\webform\Plugin\WebformHandlerInterface $handler
+   *   A webform handler.
+   * @param string $method_name
+   *   The handler method to be invoked.
+   * @param array $args
+   *   Array of arguments being passed to the handler's method.
+   *
+   * @see hook_webform_handler_invoke_alter()
+   * @see hook_webform_handler_invoke_METHOD_NAME_alter()
+   */
+  protected function invokeHandlerAlter(WebformHandlerInterface $handler, $method_name, array $args) {
+    $method_name = WebformTextHelper::camelToSnake($method_name);
+    \Drupal::moduleHandler()->alter('webform_handler_invoke', $handler, $method_name, $args);
+    \Drupal::moduleHandler()->alter('webform_handler_invoke_' . $method_name, $handler, $args);
+  }
+
+  /****************************************************************************/
+  // Element plugins.
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function invokeElements($method, &$data, &$context1 = NULL, &$context2 = NULL) {
+    /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
+    $element_manager = \Drupal::service('plugin.manager.webform.element');
+
+    $elements = $this->getElementsInitializedAndFlattened();
+    foreach ($elements as $element) {
+      $element_manager->invokeMethod($method, $element, $data, $context1, $context2);
+    }
+  }
+
+  /****************************************************************************/
+  // Variant plugins.
+  /****************************************************************************/
+
+  /**
+   * Returns the webform variant plugin manager.
+   *
+   * @return \Drupal\Component\Plugin\PluginManagerInterface
+   *   The webform variant plugin manager.
+   */
+  protected function getWebformVariantPluginManager() {
+    return \Drupal::service('plugin.manager.webform.variant');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasVariant($variant_id) {
+    return $this->getVariants()->has($variant_id);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getVariant($variant_id) {
+    return $this->getVariants()->get($variant_id);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getVariants($plugin_id = NULL, $status = NULL, $element_key = NULL) {
+    if (!$this->variantsCollection) {
+      $this->variantsCollection = new WebformVariantPluginCollection($this->getWebformVariantPluginManager(), $this->variants);
+      /** @var \Drupal\webform\Plugin\WebformVariantBase $variant */
+      foreach ($this->variantsCollection as $variant) {
+        // Initialize the variant and pass in the webform.
+        $variant->setWebform($this);
+      }
+      $this->variantsCollection->sort();
+    }
+
+    /** @var \Drupal\webform\Plugin\WebformVariantPluginCollection $variants */
+    $variants = $this->variantsCollection;
+
+    // Clone the variants if they are being filtered.
+    if (isset($plugin_id) || isset($status) || isset($element_key)) {
+      /** @var \Drupal\webform\Plugin\WebformVariantPluginCollection $variants */
+      $variants = clone $this->variantsCollection;
+    }
+
+    // Filter the variants by plugin id.
+    // This is used to limit track and enforce a variants cardinality.
+    if (isset($plugin_id)) {
+      foreach ($variants as $instance_id => $variant) {
+        if ($variant->getPluginId() !== $plugin_id) {
+          $variants->removeInstanceId($instance_id);
+        }
+      }
+    }
+
+    // Filter the variants by status.
+    // This is used to limit track and enforce a variants cardinality.
+    if (isset($status)) {
+      foreach ($variants as $instance_id => $variant) {
+        if ($variant->getStatus() !== $status) {
+          $variants->removeInstanceId($instance_id);
+        }
+      }
+    }
+
+    // Filter the variants by element key.
+    if (isset($element_key)) {
+      foreach ($variants as $instance_id => $variant) {
+        if ($variant->getElementKey() !== $element_key) {
+          $variants->removeInstanceId($instance_id);
+        }
+      }
+    }
+
+    return $variants;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addWebformVariant(WebformVariantInterface $variant) {
+    $variant->setWebform($this);
+    $variant_id = $variant->getVariantId();
+    $configuration = $variant->getConfiguration();
+    $this->getVariants()->addInstanceId($variant_id, $configuration);
+    $this->save();
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function updateWebformVariant(WebformVariantInterface $variant) {
+    $variant->setWebform($this);
+    $variant_id = $variant->getVariantId();
+    $configuration = $variant->getConfiguration();
+    $this->getVariants()->setInstanceConfiguration($variant_id, $configuration);
+    $this->save();
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteWebformVariant(WebformVariantInterface $variant) {
+    $variant->setWebform($this);
+    $this->getVariants()->removeInstanceId($variant->getVariantId());
+    $this->save();
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function applyVariants(WebformSubmissionInterface $webform_submission = NULL, $variants = [], $force = FALSE) {
+    // Get variants from webform submission.
+    if ($webform_submission) {
+      // Make sure webform submission is associated with this webform.
+      if ($webform_submission->getWebform()->id() !== $this->id()) {
+        $t_args = [
+          '@sid' => $webform_submission->id(),
+          '@webform_id' => $this->id(),
+        ];
+        throw new \Exception($this->t('Variants can not be applied because the #@sid submission was not created using @webform_id', $t_args));
+      }
+      $variants += $this->getVariantsData($webform_submission);
+    }
+
+    // Apply variants.
+    $is_applied = FALSE;
+    $variant_element_keys = $this->getElementsVariant();
+    foreach ($variant_element_keys as $varient_element_key) {
+      if (!empty($variants[$varient_element_key])) {
+        $instance_id = $variants[$varient_element_key];
+        if ($this->applyVariant($varient_element_key, $instance_id, $force)) {
+          $is_applied = TRUE;
+        }
+      }
+    }
+    if ($is_applied) {
+      $this->setOverride();
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getVariantsData(WebformSubmissionInterface $webform_submission) {
+    $variants = [];
+    $element_keys = $this->getElementsVariant();
+    foreach ($element_keys as $element_key) {
+      $variants[$element_key] = $webform_submission->getElementData($element_key);
+    }
+    return $variants;
+  }
+
+  /**
+   * Apply webform variant.
+   *
+   * @param string $element_key
+   *   The variant element key.
+   * @param string $instance_id
+   *   The variant instance id.
+   * @param bool $force
+   *   Apply disabled variants. Defaults to FALSE.
+   *
+   * @return bool
+   *   Return TRUE is variant was applied.
+   */
+  public function applyVariant($element_key, $instance_id, $force = FALSE) {
+    $element = $this->getElement($element_key);
+    // Check that the webform has a variant instance.
+    if (!$this->getVariants()->has($instance_id)) {
+      $t_args = [
+        '@title' => $element['#title'],
+        '@key' => $element_key,
+        '@instance_id' => $instance_id,
+      ];
+      // Log warning for missing variant instances.
+      \Drupal::logger('webform')->warning("The '@instance_id' variant id is missing for the '@title (@key)' variant type. <strong>No variant settings have been applied.</strong>", $t_args);
+
+      // Display onscreen warning to users who can update the webform.
+      if (\Drupal::currentUser()->hasPermission('edit webform variants')) {
+        \Drupal::messenger()->addWarning($this->t("The '@instance_id' variant id is missing for the '@title (@key)' variant type. <strong>No variant settings have been applied.</strong>", $t_args));
+      }
+      return FALSE;
+    }
+
+    $variant_plugin_id = $element['#variant'];
+    $variant_plugin = $this->getVariant($instance_id);
+
+    // Check that the variant plugin id matches the element's variant plugin id.
+    if ($variant_plugin_id !== $variant_plugin->getPluginId()) {
+      return FALSE;
+    }
+
+    // Check that the variant plugin instance is enabled.
+    if (empty($force) && $variant_plugin->isDisabled()) {
+      return FALSE;
+    }
+
+    // Apply the variant.
+    $variant_plugin->applyVariant();
+  }
+
+  /****************************************************************************/
+  // URL.
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   *
+   * Overriding so that URLs pointing to webform default to 'canonical'
+   * submission webform and not the back-end 'edit-form'.
+   */
+  public function url($rel = 'canonical', $options = []) {
+    // Do not remove this override: the default value of $rel is different.
+    return parent::url($rel, $options);
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * Overriding so that URLs pointing to webform default to 'canonical'
+   * submission webform and not the back-end 'edit-form'.
+   */
+  public function toUrl($rel = 'canonical', array $options = []) {
+    return parent::toUrl($rel, $options);
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * Overriding so that URLs pointing to webform default to 'canonical'
+   * submission webform and not the back-end 'edit-form'.
+   */
+  public function urlInfo($rel = 'canonical', array $options = []) {
+    return parent::urlInfo($rel, $options);
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * Overriding so that links to webform default to 'canonical' submission
+   * webform and not the back-end 'edit-form'.
+   */
+  public function toLink($text = NULL, $rel = 'canonical', array $options = []) {
+    return parent::toLink($text, $rel, $options);
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * Overriding so that links to webform default to 'canonical' submission
+   * webform and not the back-end 'edit-form'.
+   */
+  public function link($text = NULL, $rel = 'canonical', array $options = []) {
+    return parent::link($text, $rel, $options);
+  }
+
+  /****************************************************************************/
+  // Revisions.
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isDefaultRevision() {
+    return TRUE;
+  }
+
+  /****************************************************************************/
+  // State.
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getState($key, $default = NULL) {
+    $namespace = 'webform.webform.' . $this->id();
+    $values = \Drupal::state()->get($namespace, []);
+    return (isset($values[$key])) ? $values[$key] : $default;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setState($key, $value) {
+    $namespace = 'webform.webform.' . $this->id();
+    $values = \Drupal::state()->get($namespace, []);
+    $values[$key] = $value;
+    \Drupal::state()->set($namespace, $values);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteState($key) {
+    $namespace = 'webform.webform.' . $this->id();
+    $values = \Drupal::state()->get($namespace, []);
+    unset($values[$key]);
+    \Drupal::state()->set($namespace, $values);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasState($key) {
+    $namespace = 'webform.webform.' . $this->id();
+    $values = \Drupal::state()->get($namespace, []);
+    return (isset($values[$key])) ? TRUE : FALSE;
+  }
+
+  /****************************************************************************/
+  // User data.
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getUserData($key, $default = NULL) {
+    $account = \Drupal::currentUser();
+    /** @var \Drupal\user\UserDataInterface $user_data */
+    $user_data = \Drupal::service('user.data');
+    $values = $user_data->get('webform', $account->id(), $this->id());
+    return (isset($values[$key])) ? $values[$key] : $default;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUserData($key, $value) {
+    $account = \Drupal::currentUser();
+    /** @var \Drupal\user\UserDataInterface $user_data */
+    $user_data = \Drupal::service('user.data');
+    $values = $user_data->get('webform', $account->id(), $this->id()) ?: [];
+    $values[$key] = $value;
+    $user_data->set('webform', $account->id(), $this->id(), $values);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteUserData($key) {
+    $account = \Drupal::currentUser();
+    /** @var \Drupal\user\UserDataInterface $user_data */
+    $user_data = \Drupal::service('user.data');
+    $values = $user_data->get('webform', $account->id(), $this->id()) ?: [];
+    unset($values[$key]);
+    $user_data->set('webform', $account->id(), $this->id(), $values);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasUserData($key) {
+    $account = \Drupal::currentUser();
+    /** @var \Drupal\user\UserDataInterface $user_data */
+    $user_data = \Drupal::service('user.data');
+    $values = $user_data->get('webform', $account->id(), $this->id()) ?: [];
+    return (isset($values[$key])) ? TRUE : FALSE;
+  }
+
+  /****************************************************************************/
+  // Dependency.
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function onDependencyRemoval(array $dependencies) {
+    $changed = parent::onDependencyRemoval($dependencies);
+
+    $handlers = $this->getHandlers();
+    if (!empty($handlers)) {
+      foreach ($handlers as $handler) {
+        $plugin_definition = $handler->getPluginDefinition();
+        $provider = $plugin_definition['provider'];
+        if (in_array($provider, $dependencies['module'])) {
+          $this->deleteWebformHandler($handler);
+          $changed = TRUE;
+        }
+      }
+    }
+
+    $variants = $this->getVariants();
+    if (!empty($variants)) {
+      foreach ($variants as $variant) {
+        $plugin_definition = $variant->getPluginDefinition();
+        $provider = $plugin_definition['provider'];
+        if (in_array($provider, $dependencies['module'])) {
+          $this->deleteWebformVariant($variant);
+          $changed = TRUE;
+        }
+      }
+    }
+
+    return $changed;
+  }
+
+  /****************************************************************************/
+  // Other.
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function sort(ConfigEntityInterface $a, ConfigEntityInterface $b) {
+    $a_label = $a->get('category') . $a->label();
+    $b_label = $b->get('category') . $b->label();
+    return strnatcasecmp($a_label, $b_label);
+  }
+
+  /**
+   * Define empty array iterator.
+   *
+   * See: Issue #2759267: Undefined method Webform::getIterator().
+   */
+  public function getIterator() {
+    return new \ArrayIterator([]);
+  }
+
+  /**
+   * Define empty to string method.
+   *
+   * See: Issue #2926903: Devel Tokens tab Broken when Webform Embedded in Node.
+   *
+   * @see https://www.drupal.org/project/webform/issues/2926903
+   */
+  public function __toString() {
+    return '';
+  }
+
+}
diff --git a/web/modules/webform/src/Entity/WebformSubmission.php b/web/modules/webform/src/Entity/WebformSubmission.php
index 0f7ecc8ed4..2e59b09e3f 100644
--- a/web/modules/webform/src/Entity/WebformSubmission.php
+++ b/web/modules/webform/src/Entity/WebformSubmission.php
@@ -680,7 +680,10 @@ public function getState() {
    */
   protected function urlRouteParameters($rel) {
     $uri_route_parameters = parent::urlRouteParameters($rel);
-    $uri_route_parameters['webform'] = $this->getWebform()->id();
+    $webform = $this->getWebform();
+    if ($webform) {
+      $uri_route_parameters['webform'] = $webform->id();
+    }
     return $uri_route_parameters;
   }
 
diff --git a/web/modules/webform/src/EntitySettings/WebformEntitySettingsGeneralForm.php b/web/modules/webform/src/EntitySettings/WebformEntitySettingsGeneralForm.php
index b8058dca52..f1aed7a456 100644
--- a/web/modules/webform/src/EntitySettings/WebformEntitySettingsGeneralForm.php
+++ b/web/modules/webform/src/EntitySettings/WebformEntitySettingsGeneralForm.php
@@ -290,6 +290,7 @@ public function form(array $form, FormStateInterface $form_state) {
         'page' => $this->t('Page'),
       ],
       '#default_value' => $settings['ajax_scroll_top'],
+      '#attributes' => ['data-webform-states-no-clear' => TRUE],
     ];
     $form['ajax_settings']['ajax_container']['ajax_progress_type'] = [
       '#type' => 'select',
diff --git a/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigElementsForm.php b/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigElementsForm.php
index 62762eb0a9..ade6c9b35e 100644
--- a/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigElementsForm.php
+++ b/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigElementsForm.php
@@ -113,7 +113,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#options' => [
         'a-z0-9_' => $this->t('Lowercase letters, numbers, and underscores. (i.e. element_key)'),
         'a-zA-Z0-9_' => $this->t('Letters, numbers, and underscores. (i.e. element_KEY)'),
-        'a-z0-9_-' => $this->t('Lowercase letters, numbers, and underscores. (i.e. element-key)'),
+        'a-z0-9_-' => $this->t('Lowercase letters, numbers, underscores, and dashes. (i.e. element-key)'),
         'a-zA-Z0-9_-' => $this->t('Letters, numbers, underscores, and dashes. (i.e. element-KEY)'),
       ],
       '#required' => TRUE,
diff --git a/web/modules/webform/src/Form/WebformAjaxFormTrait.php b/web/modules/webform/src/Form/WebformAjaxFormTrait.php
index c8a6897baf..f865fa129b 100644
--- a/web/modules/webform/src/Form/WebformAjaxFormTrait.php
+++ b/web/modules/webform/src/Form/WebformAjaxFormTrait.php
@@ -200,6 +200,12 @@ public function submitAjaxForm(array &$form, FormStateInterface $form_state) {
       // Announce validation errors.
       $this->announce($this->t('Form validation errors have been found.'));
     }
+    elseif ($form_state->getResponse() instanceof AjaxResponse) {
+      // Allow developers via form_alter hooks to set their own Ajax response.
+      // The custom Ajax response could be used to close modals and refresh
+      // selected regions and blocks on the page.
+      $response = $form_state->getResponse();
+    }
     elseif ($form_state->isRebuilding()) {
       // Rebuild form.
       $response = $this->replaceForm($form, $form_state);
diff --git a/web/modules/webform/src/Form/WebformResultsExportForm.php b/web/modules/webform/src/Form/WebformResultsExportForm.php
index 2964f1c5c9..1d71ad3a69 100644
--- a/web/modules/webform/src/Form/WebformResultsExportForm.php
+++ b/web/modules/webform/src/Form/WebformResultsExportForm.php
@@ -100,14 +100,18 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
         $export_options[$key] = implode(',', $value);
       }
     }
+    $webform = $this->submissionExporter->getWebform();
     if ($source_entity = $this->submissionExporter->getSourceEntity()) {
       $entity_type = $source_entity->getEntityTypeId();
       $entity_id = $source_entity->id();
       $route_parameters = [$entity_type => $entity_id];
+      if ($webform) {
+        $route_parameters['webform'] = $webform->id();
+      }
       $route_options = ['query' => $export_options];
       $form_state->setRedirect('entity.' . $entity_type . '.webform.results_export', $route_parameters, $route_options);
     }
-    elseif ($webform = $this->submissionExporter->getWebform()) {
+    elseif ($webform) {
       $route_parameters = ['webform' => $webform->id()];
       $route_options = ['query' => $export_options];
       $form_state->setRedirect('entity.webform.results_export', $route_parameters, $route_options);
diff --git a/web/modules/webform/src/Form/WebformVariantFormBase.php b/web/modules/webform/src/Form/WebformVariantFormBase.php
index afe4cec8c5..c4ddbd8eac 100644
--- a/web/modules/webform/src/Form/WebformVariantFormBase.php
+++ b/web/modules/webform/src/Form/WebformVariantFormBase.php
@@ -154,7 +154,7 @@ public function buildForm(array $form, FormStateInterface $form_state, WebformIn
     if (count($variant_options) === 1) {
       $form['general']['element_key'] = [
         '#type' => 'value',
-        '#value' => array_key_first($variant_options),
+        '#value' => key($variant_options),
       ];
       $form['general']['element_key_item'] = [
         '#title' => $this->t('Element'),
diff --git a/web/modules/webform/src/Plugin/Field/FieldWidget/WebformEntityReferenceWidgetTrait.php b/web/modules/webform/src/Plugin/Field/FieldWidget/WebformEntityReferenceWidgetTrait.php
index 40967313b1..b0b611ece5 100644
--- a/web/modules/webform/src/Plugin/Field/FieldWidget/WebformEntityReferenceWidgetTrait.php
+++ b/web/modules/webform/src/Plugin/Field/FieldWidget/WebformEntityReferenceWidgetTrait.php
@@ -5,6 +5,8 @@
 use Drupal\Core\Datetime\DrupalDateTime;
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\webform\Element\WebformAjaxElementTrait;
+use Drupal\webform\Entity\Webform;
 use Drupal\webform\Utility\WebformDateHelper;
 use Drupal\webform\WebformInterface;
 
@@ -13,6 +15,8 @@
  */
 trait WebformEntityReferenceWidgetTrait {
 
+  use WebformAjaxElementTrait;
+
   /**
    * {@inheritdoc}
    */
@@ -96,6 +100,18 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
     // Get weight.
     $weight = $element['target_id']['#weight'];
 
+    // Get webform.
+    if ($form_state->isRebuilding()) {
+      $user_input = $form_state->getUserInput();
+      $target_id = $user_input[$field_name][$delta]['target_id'];
+    }
+    else {
+      $target_id = $items[$delta]->target_id;
+    }
+
+    /** @var \Drupal\webform\WebformInterface $webform */
+    $webform = ($target_id) ? Webform::load($target_id) : NULL;
+
     $element['settings'] = [
       '#type' => 'details',
       '#title' => $this->t('@title settings', ['@title' => $element['target_id']['#title']]),
@@ -104,6 +120,34 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
       '#weight' => $weight++,
     ];
 
+    // Disable a warning message about the webform's state using Ajax
+    $is_webform_closed = ($webform && $webform->isClosed());
+    if ($is_webform_closed) {
+      $t_args = [
+        '%webform' => $webform->label(),
+        ':href' => $webform->toUrl('settings-form')->toString(),
+      ];
+      if ($webform->access('update')) {
+        $message = $this->t('The %webform webform is <a href=":href">closed</a>. The below status will be ignored.', $t_args);
+      }
+      else {
+        $message = $this->t('The %webform webform is <strong>closed</strong>. The below status will be ignored.', $t_args);
+      }
+      $element['settings']['status_message'] = [
+        '#type' => 'webform_message',
+        '#message_type' => 'warning',
+        '#message_message' => $message,
+      ];
+    }
+    else {
+      // Render empty element so that Ajax wrapper is embedded in the page.
+      $element['settings']['status_message'] = [];
+    }
+    $ajax_id = 'webform-entity-reference-' . $field_name . '-' . $delta;
+    $this->buildAjaxElementTrigger($ajax_id, $element['target_id']);
+    $this->buildAjaxElementUpdate($ajax_id, $element);
+    $this->buildAjaxElementWrapper($ajax_id, $element['settings']['status_message']);
+
     $element['settings']['status'] = [
       '#type' => 'radios',
       '#title' => $this->t('Status'),
diff --git a/web/modules/webform/src/Plugin/WebformElement/NumericBase.php b/web/modules/webform/src/Plugin/WebformElement/NumericBase.php
index 0c233b76ce..f23f0da511 100644
--- a/web/modules/webform/src/Plugin/WebformElement/NumericBase.php
+++ b/web/modules/webform/src/Plugin/WebformElement/NumericBase.php
@@ -84,4 +84,22 @@ public function form(array $form, FormStateInterface $form_state) {
     return $form;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+    parent::validateConfigurationForm($form, $form_state);
+
+    // Validate min/max value.
+    $min = $form_state->getValue('min');
+    $max = $form_state->getValue('max');
+    if (($min === '' || !isset($min)) || ($max === '' ||  !isset($max))) {
+      return;
+    }
+
+    if ($min >= $max) {
+      $form_state->setErrorByName('min', $this->t('Minimum value can not exceed the maximum value.'));
+    }
+  }
+
 }
diff --git a/web/modules/webform/src/Plugin/WebformElement/OptionsBase.php b/web/modules/webform/src/Plugin/WebformElement/OptionsBase.php
index 3a49184d1b..424986ff9c 100644
--- a/web/modules/webform/src/Plugin/WebformElement/OptionsBase.php
+++ b/web/modules/webform/src/Plugin/WebformElement/OptionsBase.php
@@ -81,6 +81,19 @@ protected function defineDefaultProperties() {
 
   /****************************************************************************/
 
+  /**
+   * {@inheritdoc}
+   */
+  public function isMultiline(array $element) {
+    $items_format = $this->getItemsFormat($element);
+    if (strpos($items_format, 'checklist:') === 0) {
+      return TRUE;
+    }
+    else {
+      return parent::isMultiline($element);
+    }
+  }
+
   /**
    * Determine if the element plugin type includes an other option text field.
    *
@@ -311,7 +324,7 @@ protected function formatHtmlItem(array $element, WebformSubmissionInterface $we
     $format = $this->getItemFormat($element);
     switch ($format) {
       case 'raw':
-        return Markup::create($value);
+        return $value;
 
       case 'description':
         if (isset($element['#options'])) {
@@ -417,6 +430,114 @@ public function getItemsDefaultFormat() {
     return 'comma';
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function formatHtmlItems(array &$element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    $format = $this->getItemsFormat($element);
+    if (strpos($format, 'checklist:') === 0) {
+      // Get checked/unchecked icons.
+      list(, $checked_type) = explode(':', $format);
+      switch ($checked_type) {
+        case 'crosses':
+          $checked = '✖ ';
+          $unchecked = '⚬ ';
+          break;
+
+        default:
+        case 'boxes':
+          $checked = Markup::create('<span style="font-size: 1.4em; line-height: 1em">☑</span> ');
+          $unchecked = Markup::create('<span style="font-size: 1.4em; line-height: 1em">☐</span> ');
+          break;
+      }
+
+      $value = (array) $this->getValue($element, $webform_submission, $options);
+      $values = array_combine($value, $value);
+
+      // Build list of checked and unchecked options.
+      $build = [];
+      $options_description = $this->hasProperty('options_description_display');
+      foreach ($element['#options'] as $option_value => $option_text) {
+        if ($options_description && strpos($option_text, WebformOptionsHelper::DESCRIPTION_DELIMITER) !== FALSE) {
+          list($option_text) = explode(WebformOptionsHelper::DESCRIPTION_DELIMITER, $option_text);
+        }
+        $build[$option_value] = [
+          '#prefix' => isset($values[$option_value]) ? $checked : $unchecked,
+          '#markup' => $option_text,
+          '#suffix' => '<br/>',
+        ];
+        unset($values[$option_value]);
+      }
+      // Append all remaining option values.
+      foreach ($values as $value) {
+        $build[$value] = [
+          '#prefix' => $checked,
+          '#markup' => $value,
+          '#suffix' => '<br/>',
+        ];
+      }
+      return $build;
+    }
+    else {
+      return parent::formatHtmlItems($element, $webform_submission, $options);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function formatTextItems(array &$element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    $format = $this->getItemsFormat($element);
+    if (strpos($format, 'checklist:') === 0) {
+      // Get checked/unchecked icons.
+      list(, $checked_type) = explode(':', $format);
+      switch ($checked_type) {
+        case 'crosses':
+          $checked = '✖';
+          $unchecked = '⚬';
+          break;
+
+        default:
+        case 'boxes':
+          $checked = '☑';
+          $unchecked = '☐';
+          break;
+      }
+
+      $value = (array) $this->getValue($element, $webform_submission, $options);
+      $values = array_combine($value, $value);
+
+      // Build list of checked and unchecked options.
+      $list = [];
+      $options_description = $this->hasProperty('options_description_display');
+      foreach ($element['#options'] as $option_value => $option_text) {
+        if ($options_description && strpos($option_text, WebformOptionsHelper::DESCRIPTION_DELIMITER) !== FALSE) {
+          list($option_text) = explode(WebformOptionsHelper::DESCRIPTION_DELIMITER, $option_text);
+        }
+        $list[] = ((isset($values[$option_value])) ? $checked : $unchecked) . ' ' . $option_text;
+        unset($values[$option_value]);
+      }
+      // Append all remaining option values.
+      foreach ($values as $value) {
+        $list[] = $checked . ' ' . $value;
+      }
+      return implode(PHP_EOL, $list);
+    }
+    else {
+        return parent::formatTextItems($element, $webform_submission, $options);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getItemsFormats() {
+    return parent::getItemsFormats() + [
+      'checklist:boxes' => $this->t('Checklist (☑/☐)'),
+      'checklist:crosses' => $this->t('Checklist (gi)'),
+    ];
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -938,7 +1059,7 @@ public function form(array $form, FormStateInterface $form_state) {
       '#title' => $this->t('Options properties'),
       '#description' => $this->t("Custom options properties must include the 'Option value' followed by option (element) properties prepended with a hash (#) character.") .
         "<pre>option_value:
-  '#wrapper_attributes': 
+  '#wrapper_attributes':
     class:
       - disabled
   '#disabled': true</pre>" .
diff --git a/web/modules/webform/src/Plugin/WebformElement/OptionsBase.php.orig b/web/modules/webform/src/Plugin/WebformElement/OptionsBase.php.orig
new file mode 100644
index 0000000000..d57c7d7a8b
--- /dev/null
+++ b/web/modules/webform/src/Plugin/WebformElement/OptionsBase.php.orig
@@ -0,0 +1,1073 @@
+<?php
+
+namespace Drupal\webform\Plugin\WebformElement;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Form\OptGroup;
+use Drupal\Core\Mail\MailFormatHelper;
+use Drupal\Core\Render\Markup;
+use Drupal\webform\Utility\WebformArrayHelper;
+use Drupal\webform\Utility\WebformElementHelper;
+use Drupal\webform\Utility\WebformOptionsHelper;
+use Drupal\webform\Plugin\WebformElementBase;
+use Drupal\webform\Plugin\WebformElementEntityReferenceInterface;
+use Drupal\webform\Plugin\WebformElementOtherInterface;
+use Drupal\webform\WebformSubmissionConditionsValidator;
+use Drupal\webform\WebformSubmissionInterface;
+
+/**
+ * Provides a base 'options' element.
+ */
+abstract class OptionsBase extends WebformElementBase {
+
+  use TextBaseTrait;
+
+  /**
+   * Export delta for multiple options.
+   *
+   * @var bool
+   */
+  protected $exportDelta = FALSE;
+
+  /**
+   * The other option base element type.
+   *
+   * @var string
+   */
+  protected $otherOptionType;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineDefaultProperties() {
+    $properties = [
+      // Options settings.
+      'options' => [],
+      'options_randomize' => FALSE,
+    ] + parent::defineDefaultProperties();
+
+    // Add other properties to elements that include the other text field.
+    if ($this->isOptionsOther()) {
+      $properties += [
+        'other__option_label' => $this->t('Other…'),
+        'other__type' => 'textfield',
+        'other__title' => '',
+        'other__placeholder' => $this->t('Enter other…'),
+        'other__description' => '',
+        // Text field or textarea.
+        'other__size' => '',
+        'other__maxlength' => '',
+        'other__field_prefix' => '',
+        'other__field_suffix' => '',
+        // Textarea.
+        'other__rows' => '',
+        // Number.
+        'other__min' => '',
+        'other__max' => '',
+        'other__step' => '',
+        // Counter.
+        'other__counter_type' => '',
+        'other__counter_minimum' => '',
+        'other__counter_minimum_message' => '',
+        'other__counter_maximum' => '',
+        'other__counter_maximum_message' => '',
+        // Wrapper.
+        'wrapper_type' => 'fieldset',
+      ];
+    }
+
+    return $properties;
+  }
+
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isMultiline(array $element) {
+    $items_format = $this->getItemsFormat($element);
+    if (strpos($items_format, 'checklist:') === 0) {
+      return TRUE;
+    }
+    else {
+      return parent::isMultiline($element);
+    }
+  }
+
+  /**
+   * Determine if the element plugin type includes an other option text field.
+   *
+   * @return bool
+   *   TRUE if the element plugin type includes an other option text field.
+   */
+  protected function isOptionsOther() {
+    return $this->getOptionsOtherType() ? TRUE : FALSE;
+  }
+
+  /**
+   * Get the other option base element type.
+   *
+   * @return string|null
+   *   The base element type (select|radios|checkboxes|buttons).
+   */
+  protected function getOptionsOtherType() {
+    if (isset($this->otherOptionType)) {
+      return $this->otherOptionType;
+    }
+
+    if (preg_match('/webform_(select|radios|checkboxes|buttons)_other$/', $this->getPluginId(), $match)) {
+      $this->otherOptionType = $match[1];
+    }
+    else {
+      $this->otherOptionType = FALSE;
+    }
+
+    return $this->otherOptionType;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineTranslatableProperties() {
+    return array_merge(
+      parent::defineTranslatableProperties(),
+      ['options', 'empty_option', 'option_label']
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRelatedTypes(array $element) {
+    $related_types = parent::getRelatedTypes($element);
+    // Remove entity reference elements.
+    $elements = $this->elementManager->getInstances();
+    foreach ($related_types as $type => $related_type) {
+      $element_instance = $elements[$type];
+      if ($element_instance instanceof WebformElementEntityReferenceInterface) {
+        unset($related_types[$type]);
+      }
+    }
+    return $related_types;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepare(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
+    $is_wrapper_fieldset = in_array($element['#type'], ['checkboxes', 'radios', 'webform_entity_checkboxes', 'webform_entity_radios', 'webform_term_checkboxes', 'webform_toggles', 'webform_buttons']);
+    if ($is_wrapper_fieldset) {
+      // Issue #2396145: Option #description_display for webform element fieldset
+      // is not changing anything.
+      // @see core/modules/system/templates/fieldset.html.twig
+      $is_description_display = (isset($element['#description_display'])) ? TRUE : FALSE;
+      $has_description = (!empty($element['#description'])) ? TRUE : FALSE;
+      if ($is_description_display && $has_description) {
+        $description = WebformElementHelper::convertToString($element['#description']);
+        switch ($element['#description_display']) {
+          case 'before':
+            $element += ['#field_prefix' => ''];
+            $element['#field_prefix'] = '<div class="description">' . $description . '</div>' . $element['#field_prefix'];
+            unset($element['#description']);
+            unset($element['#description_display']);
+            break;
+
+          case 'tooltip':
+            $element += ['#field_suffix' => ''];
+            $element['#field_suffix'] .= '<div class="description visually-hidden">' . $description . '</div>';
+            // @see \Drupal\Core\Render\Element\CompositeFormElementTrait
+            // @see \Drupal\webform\Plugin\WebformElementBase::prepare
+            $element['#attributes']['class'][] = 'js-webform-tooltip-element';
+            $element['#attributes']['class'][] = 'webform-tooltip-element';
+            $element['#attached']['library'][] = 'webform/webform.tooltip';
+            unset($element['#description']);
+            unset($element['#description_display']);
+            break;
+
+          case 'invisible':
+            $element += ['#field_suffix' => ''];
+            $element['#field_suffix'] .= '<div class="description visually-hidden">' . $description . '</div>';
+            unset($element['#description']);
+            unset($element['#description_display']);
+            break;
+        }
+      }
+    }
+
+    parent::prepare($element, $webform_submission);
+
+    // Randomize options.
+    if (isset($element['#options']) && !empty($element['#options_randomize'])) {
+      $element['#options'] = WebformElementHelper::randomize($element['#options']);
+    }
+
+    // Options description display must be set to trigger the description display.
+    if ($this->hasProperty('options_description_display') && empty($element['#options_description_display'])) {
+      $element['#options_description_display'] = $this->getDefaultProperty('options_description_display');
+    }
+
+    // Options display must be set to trigger the options display.
+    if ($this->hasProperty('options_display') && empty($element['#options_display'])) {
+      $element['#options_display'] = $this->getDefaultProperty('options_display');
+    }
+
+    // Make sure submitted value is not lost if the element's #options were
+    // altered after the submission was completed.
+    // This only applies to the main webforom element with a #webform_key
+    // and not a webform composite's sub elements.
+    $is_completed = $webform_submission && $webform_submission->isCompleted();
+    $has_default_value = (isset($element['#default_value']) && $element['#default_value'] !== '' && $element['#default_value'] !== NULL);
+    if ($is_completed && $has_default_value && !$this->isOptionsOther() && isset($element['#webform_key'])) {
+      if ($element['#default_value'] === $webform_submission->getElementData($element['#webform_key'])) {
+        $options = OptGroup::flattenOptions($element['#options']);
+        $default_values = (array) $element['#default_value'];
+        foreach ($default_values as $default_value) {
+          if (!isset($options[$default_value])) {
+            $element['#options'][$default_value] = $default_value;
+          }
+        }
+      }
+    }
+
+    // If the element is #required and the #default_value is an empty string
+    // we need to unset the #default_value to prevent the below error.
+    // 'An illegal choice has been detected'.
+    if (!empty($element['#required']) && isset($element['#default_value']) && $element['#default_value'] === '') {
+      unset($element['#default_value']);
+    }
+
+    // Process custom options properties.
+    if ($this->hasProperty('options__properties')) {
+      $this->setElementDefaultCallback($element, 'process');
+      $element['#process'][] = [get_class($this), 'processOptionsProperties'];
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function prepareElementValidateCallbacks(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
+    if ($this->hasMultipleValues($element)) {
+      $element['#element_validate'][] = [get_class($this), 'validateMultipleOptions'];
+    }
+    parent::prepareElementValidateCallbacks($element, $webform_submission);
+  }
+
+  /**
+   * Processes options (custom) properties.
+   */
+  public static function processOptionsProperties(&$element, FormStateInterface $form_state, &$complete_form) {
+    if (empty($element['#options__properties'])) {
+      return $element;
+    }
+
+    foreach ($element['#options__properties'] as $option_key => $options__properties) {
+      if (!isset($element[$option_key])) {
+        continue;
+      }
+
+      // Remove ignored properties.
+      $options__properties = WebformElementHelper::removeIgnoredProperties($options__properties);
+
+      foreach ($options__properties as $property => $value) {
+        $option_element =& $element[$option_key];
+        if (in_array($property, ['#attributes', '#wrapper_attributes', '#label_attributes'])) {
+          // Apply attributes.
+          $option_element += [$property => []];
+          foreach ($value as $attribute_name => $attribute_value) {
+            // Merge attributes class.
+            if ($attribute_name === 'class' && isset($element[$option_key][$property][$attribute_name])) {
+              $option_element[$property][$attribute_name] = array_merge($element[$option_key][$property][$attribute_name], $attribute_value);
+            }
+            else {
+              $option_element[$property][$attribute_name] = $attribute_value;
+            }
+          }
+        }
+        else {
+          $option_element[$property] = $value;
+        }
+      }
+    }
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasMultipleWrapper() {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setDefaultValue(array &$element) {
+    if (!isset($element['#default_value'])) {
+      return;
+    }
+
+    // Compensate for #default_value not being an array, for elements that
+    // allow for multiple #options to be selected/checked.
+    if ($this->hasMultipleValues($element) && !is_array($element['#default_value'])) {
+      $element['#default_value'] = [$element['#default_value']];
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function formatHtmlItem(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    $value = $this->getValue($element, $webform_submission, $options);
+
+    $format = $this->getItemFormat($element);
+    switch ($format) {
+      case 'raw':
+        return Markup::create($value);
+
+      case 'description':
+        if (isset($element['#options'])) {
+          $options_description = $this->hasProperty('options_description_display');
+          if ($options_description) {
+            $description = WebformOptionsHelper::getOptionDescription($value, $element['#options'], $options_description);
+            return ['#markup' => $description];
+          }
+        }
+        return '';
+
+      case 'value':
+      default:
+        if (isset($element['#options'])) {
+          $options_description = $this->hasProperty('options_description_display');
+          $value = WebformOptionsHelper::getOptionText($value, $element['#options'], $options_description);
+        }
+
+        // Build a render array that uses #plain_text so that
+        // HTML characters are escaped.
+        // @see \Drupal\Core\Render\Renderer::ensureMarkupIsSafe
+        if ($value === '0') {
+          // Issue #2765609: #plain_text doesn't render empty-like values
+          // (e.g. 0 and "0").
+          // Workaround: Use #markup until this issue is fixed.
+          // @todo Remove workaround once only Drupal 8.7.x is supported.
+          $build = ['#markup' => $value];
+        }
+        else {
+          $build = ['#plain_text' => $value];
+        }
+
+        $options += ['prefixing' => TRUE];
+        if ($options['prefixing']) {
+          if (isset($element['#field_prefix'])) {
+            $build['#prefix'] = $element['#field_prefix'];
+          }
+          if (isset($element['#field_suffix'])) {
+            $build['#suffix'] = $element['#field_suffix'];
+          }
+        }
+        return $build;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function formatTextItem(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    $value = $this->getValue($element, $webform_submission, $options);
+
+    $format = $this->getItemFormat($element);
+    switch ($format) {
+      case 'raw':
+        return $value;
+
+      case 'description':
+        if (isset($element['#options'])) {
+          $options_description = $this->hasProperty('options_description_display');
+          if ($options_description) {
+            $description = WebformOptionsHelper::getOptionDescription($value, $element['#options'], $options_description);
+            if ($description) {
+              return MailFormatHelper::htmlToText($description);
+            }
+          }
+        }
+        return '';
+
+      case 'value':
+      default:
+        if (isset($element['#options'])) {
+          $options_description = $this->hasProperty('options_description_display');
+          $value = WebformOptionsHelper::getOptionText($value, $element['#options'], $options_description);
+        }
+
+        $options += ['prefixing' => TRUE];
+        if ($options['prefixing']) {
+          if (isset($element['#field_prefix'])) {
+            $value = strip_tags($element['#field_prefix']) . $value;
+          }
+          if (isset($element['#field_suffix'])) {
+            $value .= strip_tags($element['#field_suffix']);
+          }
+        }
+
+        return $value;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getItemFormats() {
+    return parent::getItemFormats() + [
+      'description' => $this->t('Option description'),
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getItemsDefaultFormat() {
+    return 'comma';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function formatHtmlItems(array &$element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    $format = $this->getItemsFormat($element);
+    if (strpos($format, 'checklist:') === 0) {
+      // Get checked/unchecked icons.
+      list(, $checked_type) = explode(':', $format);
+      switch ($checked_type) {
+        case 'crosses':
+          $checked = '✖ ';
+          $unchecked = '⚬ ';
+          break;
+
+        default:
+        case 'boxes':
+          $checked = Markup::create('<span style="font-size: 1.4em; line-height: 1em">☑</span> ');
+          $unchecked = Markup::create('<span style="font-size: 1.4em; line-height: 1em">☐</span> ');
+          break;
+      }
+
+      $value = (array) $this->getValue($element, $webform_submission, $options);
+      $values = array_combine($value, $value);
+
+      // Build list of checked and unchecked options.
+      $build = [];
+      $options_description = $this->hasProperty('options_description_display');
+      foreach ($element['#options'] as $option_value => $option_text) {
+        if ($options_description && strpos($option_text, WebformOptionsHelper::DESCRIPTION_DELIMITER) !== FALSE) {
+          list($option_text) = explode(WebformOptionsHelper::DESCRIPTION_DELIMITER, $option_text);
+        }
+        $build[$option_value] = [
+          '#prefix' => isset($values[$option_value]) ? $checked : $unchecked,
+          '#markup' => $option_text,
+          '#suffix' => '<br/>',
+        ];
+        unset($values[$option_value]);
+      }
+      // Append all remaining option values.
+      foreach ($values as $value) {
+        $build[$value] = [
+          '#prefix' => $checked,
+          '#markup' => $value,
+          '#suffix' => '<br/>',
+        ];
+      }
+      return $build;
+    }
+    else {
+      return parent::formatHtmlItems($element, $webform_submission, $options);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function formatTextItems(array &$element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    $format = $this->getItemsFormat($element);
+    if (strpos($format, 'checklist:') === 0) {
+      // Get checked/unchecked icons.
+      list(, $checked_type) = explode(':', $format);
+      switch ($checked_type) {
+        case 'crosses':
+          $checked = '✖';
+          $unchecked = '⚬';
+          break;
+
+        default:
+        case 'boxes':
+          $checked = '☑';
+          $unchecked = '☐';
+          break;
+      }
+
+      $value = (array) $this->getValue($element, $webform_submission, $options);
+      $values = array_combine($value, $value);
+
+      // Build list of checked and unchecked options.
+      $list = [];
+      $options_description = $this->hasProperty('options_description_display');
+      foreach ($element['#options'] as $option_value => $option_text) {
+        if ($options_description && strpos($option_text, WebformOptionsHelper::DESCRIPTION_DELIMITER) !== FALSE) {
+          list($option_text) = explode(WebformOptionsHelper::DESCRIPTION_DELIMITER, $option_text);
+        }
+        $list[] = ((isset($values[$option_value])) ? $checked : $unchecked) . ' ' . $option_text;
+        unset($values[$option_value]);
+      }
+      // Append all remaining option values.
+      foreach ($values as $value) {
+        $list[] = $checked . ' ' . $value;
+      }
+      return implode(PHP_EOL, $list);
+    }
+    else {
+        return parent::formatTextItems($element, $webform_submission, $options);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getItemsFormats() {
+    return parent::getItemsFormats() + [
+      'checklist:boxes' => $this->t('Checklist (☑/☐)'),
+      'checklist:crosses' => $this->t('Checklist (gi)'),
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function preview() {
+    $element = parent::preview();
+    if ($this->hasProperty('options')) {
+      $element['#options'] = [
+        'one' => 'One',
+        'two' => 'Two',
+        'three' => 'Three',
+      ];
+    }
+    if ($this->hasProperty('options_display')) {
+      $element['#options_display'] = 'side_by_side';
+    }
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTableColumn(array $element) {
+    $key = $element['#webform_key'];
+    $columns = parent::getTableColumn($element);
+    $columns['element__' . $key]['sort'] = !$this->hasMultipleValues($element);
+    return $columns;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getExportDefaultOptions() {
+    return [
+      'options_single_format' => 'compact',
+      'options_multiple_format' => 'compact',
+      'options_item_format' => 'label',
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildExportOptionsForm(array &$form, FormStateInterface $form_state, array $export_options) {
+    parent::buildExportOptionsForm($form, $form_state, $export_options);
+    if (isset($form['options'])) {
+      return;
+    }
+
+    // Build format options with help.
+    $options_format_options = [
+      'compact' => $this->t('Compact, with the option values delimited by commas in one column.') .
+        WebformOptionsHelper::DESCRIPTION_DELIMITER .
+        $this->t('Compact options are more suitable for importing data into other systems.'),
+      'separate' => $this->t('Separate, with each possible option value in its own column.') .
+        WebformOptionsHelper::DESCRIPTION_DELIMITER .
+        $this->t('Separate options are more suitable for building reports, graphs, and statistics in a spreadsheet application. Ranking will be included for sortable option elements.'),
+    ];
+    $form['options'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Select menu, radio buttons, and checkboxes options'),
+      '#open' => TRUE,
+      '#weight' => -10,
+    ];
+    $form['options']['options_single_format'] = [
+      '#type' => 'radios',
+      '#title' => $this->t('Options single value format'),
+      '#description' => $this->t('Elements that collect a single option value include select menus, radios, and buttons.'),
+      '#options' => $options_format_options,
+      '#options_description_display' => 'help',
+      '#default_value' => $export_options['options_single_format'],
+    ];
+    $form['options']['options_multiple_format'] = [
+      '#type' => 'radios',
+      '#title' => $this->t('Options multiple values format'),
+      '#description' => $this->t('Elements that collect multiple option values include multi-select, checkboxes, and toggles.'),
+      '#options' => $options_format_options,
+      '#options_description_display' => 'help',
+      '#default_value' => $export_options['options_multiple_format'],
+    ];
+    $form['options']['options_item_format'] = [
+      '#type' => 'radios',
+      '#title' => $this->t('Options item format'),
+      '#options' => [
+        'label' => $this->t('Option labels, the human-readable value (label)'),
+        'key' => $this->t('Option values, the raw value stored in the database (key)'),
+      ],
+      '#default_value' => $export_options['options_item_format'],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildExportHeader(array $element, array $options) {
+    $options_format = ($element['#webform_multiple'] ? $options['options_multiple_format'] : $options['options_single_format']);
+    if ($options_format == 'separate' && isset($element['#options'])) {
+      $header = [];
+      foreach ($element['#options'] as $option_value => $option_text) {
+        // Note: If $option_text is an array (typically a tableselect row)
+        // always use $option_value.
+        $title = ($options['options_item_format'] == 'key' || is_array($option_text)) ? $option_value : $option_text;
+        $header[] = $title;
+      }
+      // Add 'Other' option to header.
+      if ($this instanceof WebformElementOtherInterface) {
+        $header[] = ($options['options_item_format'] == 'key') ? 'other' : $this->t('Other');
+      }
+      return $this->prefixExportHeader($header, $element, $options);
+    }
+    else {
+      return parent::buildExportHeader($element, $options);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildExportRecord(array $element, WebformSubmissionInterface $webform_submission, array $export_options) {
+    $element_options = (isset($element['#options'])) ? $element['#options'] : [];
+    $options_format = ($element['#webform_multiple'] ? $export_options['options_multiple_format'] : $export_options['options_single_format']);
+    if ($options_format == 'separate') {
+      $value = $this->getRawValue($element, $webform_submission);
+
+      $record = [];
+      // Combine the values so that isset can be used instead of in_array().
+      // http://stackoverflow.com/questions/13483219/what-is-faster-in-array-or-isset
+      $deltas = FALSE;
+      if (is_array($value)) {
+        $value = array_combine($value, $value);
+        $deltas = ($this->exportDelta) ? array_flip(array_values($value)) : FALSE;
+      }
+      // Separate multiple values (i.e. options).
+      foreach ($element_options as $option_value => $option_text) {
+        if (is_array($value) && isset($value[$option_value])) {
+          unset($value[$option_value]);
+          $record[] = ($deltas) ? ($deltas[$option_value] + 1) : 'X';
+        }
+        elseif ($value == $option_value) {
+          $value = '';
+          $record[] = ($deltas) ? ($deltas[$option_value] + 1) : 'X';
+        }
+        else {
+          $record[] = '';
+        }
+      }
+      // Add 'Other' option to record.
+      if ($this instanceof WebformElementOtherInterface) {
+        $record[] = (is_array($value)) ? implode($export_options['multiple_delimiter'], $value) : $value;
+      }
+      return $record;
+    }
+    else {
+      if ($export_options['options_item_format'] == 'key') {
+        $element['#format'] = 'raw';
+      }
+      return parent::buildExportRecord($element, $webform_submission, $export_options);
+    }
+  }
+
+  /**
+   * Form API callback. Remove unchecked options from value array.
+   */
+  public static function validateMultipleOptions(array &$element, FormStateInterface $form_state, array &$completed_form) {
+    $values = $element['#value'] ?: [];
+    // Filter unchecked/unselected options whose value is 0.
+    $values = array_filter($values, function ($value) {
+      return $value !== 0;
+    });
+    $values = array_values($values);
+    $form_state->setValueForElement($element, $values);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getElementSelectorInputsOptions(array $element) {
+    if ($other_type = $this->getOptionsOtherType()) {
+      list($type) = explode(' ', $this->getPluginLabel());
+      $title = $this->getAdminLabel($element);
+      $name = $other_type;
+
+      $inputs = [];
+      $inputs[$name] = $title . ' [' . $type . ']';
+      $inputs['other'] = $title . ' [' . $this->t('Other field') . ']';
+      return $inputs;
+    }
+    else {
+      return [];
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * @see \Drupal\webform\Entity\Webform::getElementsSelectorOptions
+   */
+  public function getElementSelectorOptions(array $element) {
+    if ($this->hasMultipleValues($element) && $this->hasMultipleWrapper()) {
+      return [];
+    }
+
+    $plugin_id = $this->getPluginId();
+    $title = $this->getAdminLabel($element) . ' [' . $this->getPluginLabel() . ']';
+    $name = $element['#webform_key'];
+
+    if ($inputs = $this->getElementSelectorInputsOptions($element)) {
+      $selectors = [];
+      foreach ($inputs as $input_name => $input_title) {
+        $multiple = ($this->hasMultipleValues($element) && $input_name === 'select') ? '[]' : '';
+        $selectors[":input[name=\"{$name}[{$input_name}]$multiple\"]"] = $input_title;
+      }
+      return [$title => $selectors];
+    }
+    else {
+      $multiple = ($this->hasMultipleValues($element) && strpos($plugin_id, 'select') !== FALSE) ? '[]' : '';
+      return [":input[name=\"$name$multiple\"]" => $title];
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementSelectorSourceValues(array $element) {
+    if ($this->hasMultipleValues($element) && $this->hasMultipleWrapper()) {
+      return [];
+    }
+
+    $plugin_id = $this->getPluginId();
+    $name = $element['#webform_key'];
+    $options = OptGroup::flattenOptions($element['#options']);
+    if ($this->getElementSelectorInputsOptions($element)) {
+      $other_type = $this->getOptionsOtherType();
+      $multiple = ($this->hasMultipleValues($element) && $other_type === 'select') ? '[]' : '';
+      return [":input[name=\"{$name}[$other_type]$multiple\"]" => $options];
+    }
+    else {
+      $multiple = ($this->hasMultipleValues($element) && strpos($plugin_id, 'select') !== FALSE) ? '[]' : '';
+      return [":input[name=\"$name$multiple\"]" => $options];
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementSelectorInputValue($selector, $trigger, array $element, WebformSubmissionInterface $webform_submission) {
+    if ($this->isOptionsOther()) {
+      $input_name = WebformSubmissionConditionsValidator::getSelectorInputName($selector);
+      $other_type = WebformSubmissionConditionsValidator::getInputNameAsArray($input_name, 1);
+      $value = $this->getRawValue($element, $webform_submission);
+
+      // Handle edge case where the other element's value has
+      // not been processed.
+      // @see https://www.drupal.org/project/webform/issues/3000202
+      /** @var \Drupal\webform\Element\WebformOtherBase $class */
+      $class = $this->getFormElementClassDefinition();
+      $type = $class::getElementType();
+      if (is_array($value) && count($value) === 2 && isset($value[$type]) && isset($value['other'])) {
+        $value = $class::processValue($element, $value);
+      }
+
+      $options = OptGroup::flattenOptions($element['#options']);
+      if ($other_type === 'other') {
+        if ($this->hasMultipleValues($element)) {
+          $other_value = array_diff($value, array_keys($options));
+          return ($other_value) ? implode(', ', $other_value) : NULL;
+        }
+        else {
+          // Make sure other value is not valid option.
+          return ($value && !isset($options[$value])) ? $value : NULL;
+        }
+      }
+      else {
+        if ($this->hasMultipleValues($element)) {
+          // Return array of valid #options.
+          return array_intersect($value, array_keys($options));
+        }
+        else {
+          // Return valid #option.
+          return (isset($options[$value])) ? $value : NULL;
+        }
+      }
+    }
+    else {
+      return parent::getElementSelectorInputValue($selector, $trigger, $element, $webform_submission);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function form(array $form, FormStateInterface $form_state) {
+    $form = parent::form($form, $form_state);
+
+    $form['default']['default_value']['#description'] .= ' ' . $this->t('The default value of the field identified by its key.');
+
+    // Issue #2836374: Wrapper attributes are not supported by composite
+    // elements, this includes radios, checkboxes, and buttons.
+    if (preg_match('/(radios|checkboxes|buttons)/', $this->getPluginId())) {
+      $t_args = [
+        '@name' => mb_strtolower($this->getPluginLabel()),
+        ':href' => 'https://www.drupal.org/node/2836364',
+      ];
+      $form['element_attributes']['#description'] = $this->t('Please note: That the below custom element attributes will also be applied to the @name fieldset wrapper. (<a href=":href">Issue #2836374</a>)', $t_args);
+    }
+    // Options.
+    $form['options'] = [
+      '#type' => 'fieldset',
+      '#title' => $this->t('Element options'),
+      '#open' => TRUE,
+    ];
+    $form['options']['options'] = [
+      '#type' => 'webform_element_options',
+      '#title' => $this->t('Options'),
+      '#options_description' => $this->hasProperty('options_description_display'),
+      '#required' => TRUE,
+    ];
+
+    $form['options']['options_display_container'] = $this->getFormInlineContainer();
+    $form['options']['options_display_container']['options_display'] = [
+      '#title' => $this->t('Options display'),
+      '#type' => 'select',
+      '#options' => [
+        'one_column' => $this->t('One column'),
+        'two_columns' => $this->t('Two columns'),
+        'three_columns' => $this->t('Three columns'),
+        'side_by_side' => $this->t('Side by side'),
+        'buttons' => $this->t('Buttons'),
+      ],
+    ];
+    $form['options']['options_display_container']['options_description_display'] = [
+      '#title' => $this->t('Options description display'),
+      '#type' => 'select',
+      '#options' => [
+        'description' => $this->t('Description'),
+        'help' => $this->t('Help text'),
+      ],
+    ];
+    $form['options']['empty_option'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Empty option label'),
+      '#description' => $this->t('The label to show for the initial option denoting no selection in a select element.'),
+      '#states' => [
+        'visible' => [
+          ':input[name="properties[multiple][container][cardinality]"]' => ['value' => 'number'],
+          ':input[name="properties[multiple][container][cardinality_number]"]' => ['value' => 1],
+        ],
+      ],
+    ];
+    $default_empty_option = $this->configFactory->get('webform.settings')->get('element.default_empty_option');
+    if ($default_empty_option) {
+      $default_empty_option_required = $this->configFactory->get('webform.settings')->get('element.default_empty_option_required') ?: $this->t('- Select -');
+      $form['options']['empty_option']['#description'] .= '<br />' . $this->t('Required elements defaults to: %required', ['%required' => $default_empty_option_required]);
+      $default_empty_option_optional = $this->configFactory->get('webform.settings')->get('element.default_empty_option_optional') ?: $this->t('- None -');
+      $form['options']['empty_option']['#description'] .= '<br />' . $this->t('Optional elements defaults to: %optional', ['%optional' => $default_empty_option_optional]);
+    }
+    $form['options']['empty_value'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Empty option value'),
+      '#description' => $this->t('The value for the initial option denoting no selection in a select element, which is used to determine whether the user submitted a value or not.'),
+      '#states' => [
+        'visible' => [
+          ':input[name="properties[multiple][container][cardinality]"]' => ['value' => 'number'],
+          ':input[name="properties[multiple][container][cardinality_number]"]' => ['value' => 1],
+        ],
+      ],
+    ];
+
+    $form['options']['options_randomize'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Randomize options'),
+      '#description' => $this->t('Randomizes the order of the options when they are displayed in the webform.'),
+      '#return_value' => TRUE,
+    ];
+
+    // Other.
+    $states_textfield_or_number = [
+      'visible' => [
+        [':input[name="properties[other__type]"]' => ['value' => 'textfield']],
+        'or',
+        [':input[name="properties[other__type]"]' => ['value' => 'number']],
+      ],
+    ];
+    $states_textbase = [
+      'visible' => [
+        [':input[name="properties[other__type]"]' => ['value' => 'textfield']],
+        'or',
+        [':input[name="properties[other__type]"]' => ['value' => 'textarea']],
+      ],
+    ];
+    $states_textarea = [
+      'visible' => [
+        ':input[name="properties[other__type]"]' => ['value' => 'textarea'],
+      ],
+    ];
+    $states_number = [
+      'visible' => [
+        ':input[name="properties[other__type]"]' => ['value' => 'number'],
+      ],
+    ];
+    $form['options_other'] = [
+      '#type' => 'fieldset',
+      '#title' => $this->t('Other option settings'),
+    ];
+    $form['options_other']['other__type'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Other type'),
+      '#options' => [
+        'textfield' => $this->t('Text field'),
+        'textarea' => $this->t('Textarea'),
+        'number' => $this->t('Number'),
+      ],
+    ];
+    $form['options_other']['other__option_label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Other option label'),
+    ];
+    $form['options_other']['other__title'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Other title'),
+    ];
+    $form['options_other']['other__placeholder'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Other placeholder'),
+    ];
+    $form['options_other']['other__description'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Other description'),
+    ];
+
+    $form['options_other']['other__field_container'] = $this->getFormInlineContainer();
+    $form['options_other']['other__field_container']['other__field_prefix'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Other field prefix'),
+      '#description' => $this->t('Text or code that is placed directly in front of the input. This can be used to prefix an input with a constant string. Examples: $, #, -.'),
+      '#size' => 10,
+      '#states' => $states_textfield_or_number,
+    ];
+    $form['options_other']['other__field_container']['other__field_suffix'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Other field suffix'),
+      '#description' => $this->t('Text or code that is placed directly after the input. This can be used to add a unit to an input. Examples: lb, kg, %.'),
+      '#size' => 10,
+      '#states' => $states_textfield_or_number,
+    ];
+    $form['options_other']['other__size_container'] = $this->getFormInlineContainer();
+    $form['options_other']['other__size_container']['other__size'] = [
+      '#type' => 'number',
+      '#title' => $this->t('Other size'),
+      '#description' => $this->t('Leaving blank will use the default size.'),
+      '#min' => 1,
+      '#size' => 4,
+      '#states' => $states_textfield_or_number,
+    ];
+    $form['options_other']['other__size_container']['other__maxlength'] = [
+      '#type' => 'number',
+      '#title' => $this->t('Other maxlength'),
+      '#description' => $this->t('Leaving blank will use the default maxlength.'),
+      '#min' => 1,
+      '#size' => 4,
+      '#states' => $states_textfield_or_number,
+    ];
+    $form['options_other']['other__size_container']['other__rows'] = [
+      '#type' => 'number',
+      '#title' => $this->t('Other rows'),
+      '#description' => $this->t('Leaving blank will use the default rows.'),
+      '#min' => 1,
+      '#size' => 4,
+      '#states' => $states_textarea,
+    ];
+
+    $form['options_other']['other__number_container'] = $this->getFormInlineContainer();
+    $form['options_other']['other__number_container']['other__min'] = [
+      '#type' => 'number',
+      '#title' => $this->t('Other minimum'),
+      '#description' => $this->t('Specifies the minimum value.'),
+      '#step' => 'any',
+      '#size' => 4,
+      '#states' => $states_number,
+    ];
+    $form['options_other']['other__number_container']['other__max'] = [
+      '#type' => 'number',
+      '#title' => $this->t('Other maximum'),
+      '#description' => $this->t('Specifies the maximum value.'),
+      '#step' => 'any',
+      '#size' => 4,
+      '#states' => $states_number,
+    ];
+    $form['options_other']['other__number_container']['other__step'] = [
+      '#type' => 'number',
+      '#title' => $this->t('Other steps'),
+      '#description' => $this->t('Specifies the legal number intervals. Leave blank to support any number interval.'),
+      '#step' => 'any',
+      '#size' => 4,
+      '#states' => $states_number,
+    ];
+
+    $form['options_other']['other__textbase_container'] = [
+      '#type' => 'container',
+      '#states' => $states_textbase,
+    ] + $this->buildCounterForm('other__', 'Other count');
+
+    // Add hide/show #format_items based on #multiple.
+    if ($this->supportsMultipleValues() && $this->hasProperty('multiple')) {
+      $form['display']['format_items']['#states'] = [
+        'visible' => [
+          [':input[name="properties[multiple]"]' => ['checked' => TRUE]],
+        ],
+      ];
+    }
+
+    $form['options_properties'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Options (custom) properties'),
+      '#access' => $this->currentUser->hasPermission('edit webform source'),
+    ];
+    $form['options_properties']['options__properties'] = [
+      '#type' => 'webform_codemirror',
+      '#mode' => 'yaml',
+      '#title' => $this->t('Options properties'),
+      '#description' => $this->t("Custom options properties must include the 'Option value' followed by option (element) properties prepended with a hash (#) character.") .
+        "<pre>option_value:
+  '#wrapper_attributes':
+    class:
+      - disabled
+  '#disabled': true</pre>" .
+        '<br /><br />' .
+        $this->t('These properties and callbacks are not allowed: @properties', ['@properties' => WebformArrayHelper::toString(WebformArrayHelper::addPrefix(WebformElementHelper::$ignoredProperties))]),
+    ];
+
+    return $form;
+  }
+
+}
diff --git a/web/modules/webform/src/Plugin/WebformElement/Telephone.php b/web/modules/webform/src/Plugin/WebformElement/Telephone.php
index f681977120..a555fd5f47 100644
--- a/web/modules/webform/src/Plugin/WebformElement/Telephone.php
+++ b/web/modules/webform/src/Plugin/WebformElement/Telephone.php
@@ -31,7 +31,7 @@ protected function defineDefaultProperties() {
         'international' => FALSE,
         'international_initial_country' => '',
         'international_preferred_countries' => [],
-      ] + parent::defineDefaultProperties();
+      ] + parent::defineDefaultProperties() + $this->defineDefaultMultipleProperties();
     // Add support for telephone_validation.module.
     if (\Drupal::moduleHandler()->moduleExists('telephone_validation')) {
       $properties += [
diff --git a/web/modules/webform/src/Plugin/WebformElement/TextBase.php b/web/modules/webform/src/Plugin/WebformElement/TextBase.php
index 27f9db57e6..189d2d0cab 100644
--- a/web/modules/webform/src/Plugin/WebformElement/TextBase.php
+++ b/web/modules/webform/src/Plugin/WebformElement/TextBase.php
@@ -3,6 +3,7 @@
 namespace Drupal\webform\Plugin\WebformElement;
 
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\webform\Element\WebformHtmlEditor;
 use Drupal\webform\Plugin\WebformElementBase;
 use Drupal\webform\Utility\WebformElementHelper;
 use Drupal\webform\Utility\WebformHtmlHelper;
@@ -71,9 +72,16 @@ public function prepare(array &$element, WebformSubmissionInterface $webform_sub
         'counter_maximum_message',
       ];
       foreach ($data_attributes as $data_attribute) {
-        if (!empty($element['#' . $data_attribute])) {
-          $element['#attributes']['data-' . str_replace('_', '-', $data_attribute)] = $element['#' . $data_attribute];
+        if (empty($element['#' . $data_attribute])) {
+          continue;
         }
+
+        $data_attribute_name = 'data-' . str_replace('_', '-', $data_attribute);
+        $data_attribute_value = $element['#' . $data_attribute];
+        if (in_array($data_attribute, ['counter_minimum_message', 'counter_maximum_message'])) {
+          $data_attribute_value = WebformHtmlEditor::stripTags($data_attribute_value);
+        }
+        $element['#attributes'][$data_attribute_name] = $data_attribute_value;
       }
 
       $element['#attributes']['class'][] = 'js-webform-counter';
@@ -164,6 +172,7 @@ public function form(array $form, FormStateInterface $form_state) {
       '#title' => $this->t('Pattern'),
       '#description' => $this->t('A <a href=":href">regular expression</a> that the element\'s value is checked against.', [':href' => 'http://www.w3schools.com/js/js_regexp.asp']),
       '#value__title' => $this->t('Pattern regular expression'),
+      '#value__description' => $this->t('Enter a <a href=":href">regular expression</a> that the element\'s value should match.', [':href' => 'http://www.w3schools.com/js/js_regexp.asp']),
       '#value__maxlength' => NULL,
     ];
     $form['validation']['pattern_error'] = [
diff --git a/web/modules/webform/src/Plugin/WebformElement/TextBase.php.orig b/web/modules/webform/src/Plugin/WebformElement/TextBase.php.orig
new file mode 100644
index 0000000000..d158369e9b
--- /dev/null
+++ b/web/modules/webform/src/Plugin/WebformElement/TextBase.php.orig
@@ -0,0 +1,438 @@
+<?php
+
+namespace Drupal\webform\Plugin\WebformElement;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\webform\Plugin\WebformElementBase;
+use Drupal\webform\Utility\WebformElementHelper;
+use Drupal\webform\Utility\WebformHtmlHelper;
+use Drupal\webform\Utility\WebformTextHelper;
+use Drupal\webform\WebformSubmissionInterface;
+
+/**
+ * Provides a base 'text' (field) class.
+ */
+abstract class TextBase extends WebformElementBase {
+
+  use TextBaseTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineDefaultProperties() {
+    return [
+      'readonly' => FALSE,
+      'size' => NULL,
+      'minlength' => NULL,
+      'maxlength' => NULL,
+      'placeholder' => '',
+      'autocomplete' => 'on',
+      'pattern' => '',
+      'pattern_error' => '',
+    ] + parent::defineDefaultProperties();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineTranslatableProperties() {
+    return array_merge(parent::defineTranslatableProperties(), ['counter_minimum_message', 'counter_maximum_message', 'pattern_error']);
+  }
+
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepare(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
+    parent::prepare($element, $webform_submission);
+
+    // Counter.
+    if (!empty($element['#counter_type'])
+      && (!empty($element['#counter_minimum']) || !empty($element['#counter_maximum']))
+      && $this->librariesManager->isIncluded('jquery.textcounter')) {
+
+      // Apply character min/max to min/max length.
+      if ($element['#counter_type'] == 'character') {
+        if (!empty($element['#counter_minimum'])) {
+          $element['#minlength'] = $element['#counter_minimum'];
+        }
+        if (!empty($element['#counter_maximum'])) {
+          $element['#maxlength'] = $element['#counter_maximum'];
+        }
+      }
+
+      // Set 'data-counter-*' attributes using '#counter_*' properties.
+      $data_attributes = [
+        'counter_type',
+        'counter_minimum',
+        'counter_minimum_message',
+        'counter_maximum',
+        'counter_maximum_message',
+      ];
+      foreach ($data_attributes as $data_attribute) {
+        if (!empty($element['#' . $data_attribute])) {
+          $element['#attributes']['data-' . str_replace('_', '-', $data_attribute)] = $element['#' . $data_attribute];
+        }
+      }
+
+      $element['#attributes']['class'][] = 'js-webform-counter';
+      $element['#attributes']['class'][] = 'webform-counter';
+      $element['#attached']['library'][] = 'webform/webform.element.counter';
+
+      $element['#element_validate'][] = [get_class($this), 'validateCounter'];
+    }
+
+    // Input mask.
+    if (!empty($element['#input_mask']) && $this->librariesManager->isIncluded('jquery.inputmask')) {
+      // See if the element mask is JSON by looking for 'name':, else assume it
+      // is a mask pattern.
+      $input_mask = $element['#input_mask'];
+      if (preg_match("/^'[^']+'\s*:/", $input_mask)) {
+        $element['#attributes']['data-inputmask'] = $input_mask;
+      }
+      else {
+        $element['#attributes']['data-inputmask-mask'] = $input_mask;
+      }
+      // Set input mask #pattern.
+      $input_masks = $this->getInputMasks();
+      if (isset($input_masks[$input_mask])
+        && isset($input_masks[$input_mask]['pattern']) &&
+        empty($element['#pattern'])) {
+        $element['#pattern'] = $input_masks[$input_mask]['pattern'];
+      }
+
+      $element['#attributes']['class'][] = 'js-webform-input-mask';
+      $element['#attached']['library'][] = 'webform/webform.element.inputmask';
+      $element['#element_validate'][] = [get_called_class(), 'validateInputMask'];
+    }
+
+    // Input hiding.
+    if (!empty($element['#input_hide'])) {
+      $element['#attributes']['class'][] = 'js-webform-input-hide';
+      $element['#attached']['library'][] = 'webform/webform.element.inputhide';
+    }
+
+    // Pattern validation.
+    // This override core's pattern validation to support unicode
+    // and a custom error message.
+    if (isset($element['#pattern'])) {
+      $element['#attributes']['pattern'] = $element['#pattern'];
+      $element['#element_validate'][] = [get_called_class(), 'validatePattern'];
+
+      // Set pattern error message using #pattern_error.
+      // @see Drupal.behaviors.webformRequiredError
+      // @see webform.form.js
+      if (!empty($element['#pattern_error'])) {
+        $element['#attributes']['data-webform-pattern-error'] = WebformHtmlHelper::toPlainText($element['#pattern_error']);
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function form(array $form, FormStateInterface $form_state) {
+    $form = parent::form($form, $form_state);
+
+    // Input mask.
+    $form['form']['input_mask'] = [
+      '#type' => 'webform_select_other',
+      '#title' => $this->t('Input masks'),
+      '#description' => $this->t('An <a href=":href">inputmask</a> helps the user with the element by ensuring a predefined format.', [':href' => 'https://github.com/RobinHerbots/jquery.inputmask']),
+      '#other__option_label' => $this->t('Custom…'),
+      '#other__placeholder' => $this->t('Enter input mask…'),
+      '#other__description' => $this->t('(9 = numeric; a = alphabetical; * = alphanumeric)'),
+      '#empty_option' => $this->t('- None -'),
+      '#options' => $this->getInputMaskOptions(),
+    ];
+    if ($this->librariesManager->isExcluded('jquery.inputmask')) {
+      $form['form']['input_mask']['#access'] = FALSE;
+    }
+
+    // Input hiding.
+    $form['form']['input_hide'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Input hiding'),
+      '#description' => $this->t('Hide the input of the element when the input is not being focused.'),
+      '#return_value' => TRUE,
+    ];
+
+    // Pattern.
+    $form['validation']['pattern'] = [
+      '#type' => 'webform_checkbox_value',
+      '#title' => $this->t('Pattern'),
+      '#description' => $this->t('A <a href=":href">regular expression</a> that the element\'s value is checked against.', [':href' => 'http://www.w3schools.com/js/js_regexp.asp']),
+      '#value__title' => $this->t('Pattern regular expression'),
+      '#value__description' => $this->t('Enter a <a href=":href">regular expression</a> that the element\'s value should match.', [':href' => 'http://www.w3schools.com/js/js_regexp.asp']),
+      '#value__maxlength' => NULL,
+    ];
+    $form['validation']['pattern_error'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Pattern message'),
+      '#description' => $this->t('If set, this message will be used when a pattern is not matched, instead of the default "@message" message.', ['@message' => t('%name field is not in the right format.')]),
+      '#states' => [
+        'visible' => [
+          ':input[name="properties[pattern][checkbox]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+
+    // Counter.
+    $form['validation'] += $this->buildCounterForm();
+
+    if (isset($form['form']['maxlength'])) {
+      $form['form']['maxlength']['#description'] .= ' ' . $this->t('If character counter is enabled, maxlength will automatically be set to the count maximum.');
+      $form['form']['maxlength']['#states'] = [
+        'invisible' => [
+          ':input[name="properties[counter_type]"]' => ['value' => 'character'],
+        ],
+      ];
+    }
+
+    return $form;
+  }
+
+  /**
+   * Form API callback. Validate (word/character) counter.
+   */
+  public static function validateCounter(array &$element, FormStateInterface $form_state) {
+    $value = $element['#value'];
+    if ($value === '') {
+      return;
+    }
+
+    $type = $element['#counter_type'];
+    $max = (!empty($element['#counter_maximum'])) ? $element['#counter_maximum'] : NULL;
+    $min = (!empty($element['#counter_minimum'])) ? $element['#counter_minimum'] : NULL;
+
+    // Display error.
+    // @see \Drupal\Core\Form\FormValidator::performRequiredValidation
+    $t_args = [
+      '@type' => ($type == 'character') ? t('characters') : t('words'),
+      '@name' => $element['#title'],
+      '%max' => $max,
+      '%min' => $min,
+    ];
+
+    // Get character/word count.
+    if ($type === 'character') {
+      $length = mb_strlen($value);
+      $t_args['%length'] = $length;
+    }
+    // Validate word count.
+    elseif ($type === 'word') {
+      $length = WebformTextHelper::wordCount($value);
+      $t_args['%length'] = $length;
+    }
+
+    // Validate character/word count.
+    if ($max && $length > $max) {
+      $form_state->setError($element, t('@name cannot be longer than %max @type but is currently %length @type long.', $t_args));
+    }
+    elseif ($min && $length < $min) {
+      $form_state->setError($element, t('@name must be longer than %min @type but is currently %length @type long.', $t_args));
+    }
+  }
+
+  /**
+   * Form API callback. Validate input mask and display required error message.
+   *
+   * Makes sure a required element's value doesn't include the default
+   * input mask as the submitted value.
+   *
+   * Applies only to the currency input mask.
+   */
+  public static function validateInputMask(&$element, FormStateInterface $form_state, &$complete_form) {
+    // Set required error when input mask is submitted.
+    if (!empty($element['#required'])
+      && static::isDefaultInputMask($element, $element['#value'])) {
+      WebformElementHelper::setRequiredError($element, $form_state);
+    }
+  }
+
+  /**
+   * Check if an element's value is the input mask's default value.
+   *
+   * @param array $element
+   *   An element.
+   * @param string $value
+   *   A value.
+   *
+   * @return bool
+   *   TRUE if an element's value is the input mask's default value.
+   */
+  public static function isDefaultInputMask(array $element, $value) {
+    if (empty($element['#input_mask']) || $value === '') {
+      return FALSE;
+    }
+
+    $input_mask = $element['#input_mask'];
+    $input_masks = [
+      "'alias': 'currency'" => '$ 0.00',
+    ];
+    return (isset($input_masks[$input_mask]) && $input_masks[$input_mask] === $value) ? TRUE : FALSE;
+  }
+
+  /**
+   * Form API callback. Validate unicode pattern and display a custom error.
+   *
+   * @see https://www.drupal.org/project/drupal/issues/2633550
+   */
+  public static function validatePattern(&$element, FormStateInterface $form_state, &$complete_form) {
+    if ($element['#value'] !== '') {
+      // PHP: Convert JavaScript-escaped Unicode characters to PCRE
+      // escape sequence format.
+      // @see https://bytefreaks.net/programming-2/php-programming-2/php-convert-javascript-escaped-unicode-characters-to-html-hex-references˚
+      $pcre_pattern = preg_replace('/\\\\u([a-fA-F0-9]{4})/', '\\x{\\1}', $element['#pattern']);
+      $pattern = '{^(?:' . $pcre_pattern . ')$}u';
+      if (!preg_match($pattern, $element['#value'])) {
+        if (!empty($element['#pattern_error'])) {
+          $form_state->setError($element, WebformHtmlHelper::toHtmlMarkup($element['#pattern_error']));
+        }
+        else {
+          $form_state->setError($element, t('%name field is not in the right format.', ['%name' => $element['#title']]));
+        }
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+    parent::validateConfigurationForm($form, $form_state);
+    $properties = $this->getConfigurationFormProperties($form, $form_state);
+
+    // Validate #pattern's regular expression.
+    // @see \Drupal\Core\Render\Element\FormElement::validatePattern
+    // @see http://stackoverflow.com/questions/4440626/how-can-i-validate-regex
+    if (!empty($properties['#pattern'])) {
+      set_error_handler('_webform_entity_element_validate_rendering_error_handler');
+
+      // PHP: Convert JavaScript-escaped Unicode characters to PCRE escape
+      // sequence format.
+      // @see https://bytefreaks.net/programming-2/php-programming-2/php-convert-javascript-escaped-unicode-characters-to-html-hex-references
+      $pcre_pattern = preg_replace('/\\\\u([a-fA-F0-9]{4})/', '\\x{\\1}', $properties['#pattern']);
+
+      if (preg_match('{^(?:' . $pcre_pattern . ')$}u', NULL) === FALSE) {
+        $form_state->setErrorByName('pattern', t('Pattern %pattern is not a valid regular expression.', ['%pattern' => $properties['#pattern']]));
+      }
+
+      set_error_handler('_drupal_error_handler');
+    }
+
+    // Validate #counter_maximum.
+    if (!empty($properties['#counter_type']) && empty($properties['#counter_maximum']) && empty($properties['#counter_minimum'])) {
+      $form_state->setErrorByName('counter_minimum', t('Counter minimum or maximum is required.'));
+      $form_state->setErrorByName('counter_maximum', t('Counter minimum or maximum is required.'));
+    }
+  }
+
+  /****************************************************************************/
+  // Input masks.
+  /****************************************************************************/
+
+  /**
+   * Get input masks.
+   *
+   * @return array
+   *   An associative array keyed my input mask contain input mask title,
+   *   example, and patterh.
+   */
+  protected function getInputMasks() {
+    $input_masks = [
+      "'alias': 'currency'" => [
+        'title' => $this->t('Currency'),
+        'example' => '$ 9.99',
+        'pattern' => '^\$ [0-9]{1,3}(,[0-9]{3})*.\d\d$',
+      ],
+      "'alias': 'datetime'" => [
+        'title' => $this->t('Date'),
+        'example' => '2007-06-09\'T\'17:46:21',
+      ],
+      "'alias': 'decimal'" => [
+        'title' => $this->t('Decimal'),
+        'example' => '1.234',
+        'pattern' => '^\d+(\.\d+)?$',
+      ],
+      "'alias': 'email'" => [
+        'title' => $this->t('Email'),
+        'example' => 'example@example.com',
+      ],
+      "'alias': 'ip'" => [
+        'title' => $this->t('IP address'),
+        'example' => '255.255.255.255',
+        'pattern' => '^\d\d\d\.\d\d\d\.\d\d\d\.\d\d\d$',
+      ],
+      '[9-]AAA-999' => [
+        'title' => $this->t('License plate'),
+        'example' => '[9-]AAA-999',
+      ],
+      "'alias': 'mac'" => [
+        'title' => $this->t('MAC address'),
+        'example' => '99-99-99-99-99-99',
+        'pattern' => '^\d\d-\d\d-\d\d-\d\d-\d\d-\d\d$',
+      ],
+      "'alias': 'percentage'" => [
+        'title' => $this->t('Percentage'),
+        'example' => '99 %',
+        'pattern' => '^\d+ %$',
+      ],
+      '(999) 999-9999' => [
+        'title' => $this->t('Phone'),
+        'example' => '(999) 999-9999',
+        'pattern' => '^\(\d\d\d\) \d\d\d-\d\d\d\d$',
+      ],
+      '999-99-9999' => [
+        'title' => $this->t('Social Security Number (SSN)'),
+        'example' => '999-99-9999',
+        'pattern' => '^\d\d\d-\d\d-\d\d\d\d$',
+      ],
+      "'alias': 'vin'" => [
+        'title' => $this->t('Vehicle identification number (VIN)'),
+        'example' => 'JA3AY11A82U020534',
+      ],
+      '99999[-9999]' => [
+        'title' => $this->t('ZIP Code'),
+        'example' => '99999[-9999]',
+        'pattern' => '^\d\d\d\d\d(-\d\d\d\d)?$',
+      ],
+      "'casing': 'upper'" => [
+        'title' => $this->t('Uppercase'),
+        'example' => 'UPPERCASE',
+      ],
+      "'casing': 'lower'" => [
+        'title' => $this->t('Lowercase'),
+        'example' => 'lowercase',
+      ],
+    ];
+
+    // Get input masks.
+    $modules = \Drupal::moduleHandler()->getImplementations('webform_element_input_masks');
+    foreach ($modules as $module) {
+      $input_masks += \Drupal::moduleHandler()->invoke($module, 'webform_element_input_masks');
+    }
+
+    // Alter input masks.
+    \Drupal::moduleHandler()->alter('webform_element_input_masks', $input_masks);
+
+    return $input_masks;
+  }
+
+  /**
+   * Get input masks as select menu options.
+   *
+   * @return array
+   *   An associative array of options.
+   */
+  protected function getInputMaskOptions() {
+    $input_masks = $this->getInputMasks();
+    $options = [];
+    foreach ($input_masks as $input_mask => $settings) {
+      $options[$input_mask] = $settings['title'] . (!empty($settings['example']) ? ' - ' . $settings['example'] : '');
+    }
+    return $options;
+  }
+
+}
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformCompositeBase.php b/web/modules/webform/src/Plugin/WebformElement/WebformCompositeBase.php
index 558ccff5f6..b11b243193 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformCompositeBase.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformCompositeBase.php
@@ -835,7 +835,7 @@ public function form(array $form, FormStateInterface $form_state) {
 
     // Update #required label.
     $form['validation']['required_container']['required']['#title'] .= ' <em>' . $this->t('(Display purposes only)') . '</em>';
-    $form['validation']['required_container']['required']['#description'] = $this->t('If checked, adds required indicator to the title, if visible. To enforce individual fields, also tick "Required" under the @name settings above.', ['@name' => $this->getPluginLabel()]);
+    $form['validation']['required_container']['required']['#description'] = $this->t('If checked, adds required indicator to the title, if visible. To required individual elements, also tick "Required" under the @name settings above.', ['@name' => $this->getPluginLabel()]);
 
     // Update '#multiple__header_label'.
     $form['element']['multiple__header_container']['multiple__header_label']['#states']['visible'][':input[name="properties[multiple__header]"]'] = ['checked' => FALSE];
@@ -1415,7 +1415,7 @@ public function postDelete(array &$element, WebformSubmissionInterface $webform_
    * @return array
    *   An array of managed file element keys.
    */
-  protected function getManagedFiles(array $element) {
+  public function getManagedFiles(array $element) {
     $id = $element['#webform_id'];
 
     if (isset($this->elementsManagedFiles[$id])) {
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformManagedFileBase.php b/web/modules/webform/src/Plugin/WebformElement/WebformManagedFileBase.php
index 61a0a1a329..2379fd2264 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformManagedFileBase.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformManagedFileBase.php
@@ -15,6 +15,7 @@
 use Drupal\Core\Language\LanguageManagerInterface;
 use Drupal\Core\Link;
 use Drupal\Core\Render\Element;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\Url as UrlGenerator;
 use Drupal\Core\Render\ElementInfoManagerInterface;
 use Drupal\Core\Session\AccountInterface;
@@ -899,6 +900,19 @@ public function previewManagedFile(array $element, WebformSubmissionInterface $w
    * Form API callback. Consolidate the array of fids for this field into a single fids.
    */
   public static function validateManagedFile(array &$element, FormStateInterface $form_state, &$complete_form) {
+    // Issue #3130448: Add custom #required_message support to
+    // ManagedFile elements.
+    // @see https://www.drupal.org/project/drupal/issues/3130448
+    if (!empty($element['#required_error'])) {
+      $errors = $form_state->getErrors();
+      $key = $element['#webform_key'];
+      if (isset($errors[$key])
+        && $errors[$key] instanceof TranslatableMarkup
+        && $errors[$key]->getUntranslatedString() === '@name field is required.') {
+        $errors[$key]->__construct($element['#required_error']);
+      }
+    }
+
     if (!empty($element['#files'])) {
       $fids = array_keys($element['#files']);
       if (empty($element['#multiple'])) {
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformScale.php b/web/modules/webform/src/Plugin/WebformElement/WebformScale.php
new file mode 100644
index 0000000000..5e76b5706e
--- /dev/null
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformScale.php
@@ -0,0 +1,117 @@
+<?php
+
+namespace Drupal\webform\Plugin\WebformElement;
+
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * Provides a 'scale' element.
+ *
+ * @WebformElement(
+ *   id = "webform_scale",
+ *   label = @Translation("Scale"),
+ *   description = @Translation("Provides a form element for input of a numeric scale."),
+ *   category = @Translation("Advanced elements"),
+ * )
+ */
+class WebformScale extends NumericBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineDefaultProperties() {
+    $properties = [
+      'min' => 1,
+      'max' => 5,
+      'min_text' => '',
+      'max_text' => '',
+      'scale_size' => 'medium',
+      'scale_type' => 'circle',
+      'scale_text' => 'below',
+      // Wrapper.
+      'wrapper_type' => 'fieldset',
+    ] + parent::defineDefaultProperties();
+    unset(
+      $properties['size'],
+      $properties['minlength'],
+      $properties['maxlength'],
+      $properties['placeholder'],
+      $properties['autocomplete'],
+      $properties['format_items'],
+      $properties['format_items_html'],
+      $properties['format_items_text']
+    );
+    return $properties;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function preview() {
+    return parent::preview() + [
+      '#min' => 1,
+      '#max' => 5,
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function form(array $form, FormStateInterface $form_state) {
+    $form = parent::form($form, $form_state);
+
+    $form['number']['#title'] = $this->t('Scale settings');
+
+    $form['number']['number_container']['min']['#min'] = 0;
+    $form['number']['number_container']['min']['#step'] = 1;
+    $form['number']['number_container']['min']['#required'] = TRUE;
+
+    $form['number']['number_container']['max']['#min'] = 0;
+    $form['number']['number_container']['max']['#step'] = 1;
+    $form['number']['number_container']['max']['#required'] = TRUE;
+
+    $form['number']['min_text'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Minimum label'),
+      '#description' => $this->t('Label for the minimum value in the scale.'),
+    ];
+    $form['number']['max_text'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Maximum label'),
+      '#description' => $this->t('Label for the maximum value in the scale.'),
+    ];
+
+    $form['number']['scale_container'] = $this->getFormInlineContainer();
+    $form['number']['scale_container']['scale_size'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Scale size'),
+      '#options' => [
+        'small' => $this->t('Small (@size)', ['@size' => '24px']),
+        'medium' => $this->t('Medium (@size)', ['@size' => '36px']),
+        'large' => $this->t('Large (@size)', ['@size' => '48px']),
+      ],
+      '#required' => TRUE,
+    ];
+    $form['number']['scale_container']['scale_type'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Scale type'),
+      '#options' => [
+        'circle' => $this->t('Circle'),
+        'square' => $this->t('Square'),
+        'flexbox' => $this->t('Flexbox'),
+      ],
+      '#required' => TRUE,
+    ];
+    $form['number']['scale_container']['scale_text'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Scale text'),
+      '#options' => [
+        'above' => $this->t('Above'),
+        'below' => $this->t('Below'),
+      ],
+      '#required' => TRUE,
+    ];
+    return $form;
+  }
+
+}
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformSignature.php b/web/modules/webform/src/Plugin/WebformElement/WebformSignature.php
index d1d7949c93..f48779122d 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformSignature.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformSignature.php
@@ -5,6 +5,7 @@
 use Drupal\Component\Utility\Crypt;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Site\Settings;
+use Drupal\webform\Element\WebformSignature as WebformSignatureElement;
 use Drupal\webform\Plugin\WebformElementBase;
 use Drupal\webform\WebformInterface;
 use Drupal\webform\WebformSubmissionInterface;
@@ -135,16 +136,17 @@ protected function formatHtmlItem(array $element, WebformSubmissionInterface $we
           return '[' . $this->t('not signed') . ']';
         }
 
-        return [
+        $src = $this->getImageUrl($element, $webform_submission, $options);
+        return $src ? [
           '#type' => 'html_tag',
           '#tag' => 'img',
           '#attributes' => [
-            'src' => $this->getImageUrl($element, $webform_submission, $options),
+            'src' => $src,
             'alt' => $this->t('Signature'),
             'class' => ['webform-signature-image'],
           ],
           '#attached' => ['library' => ['webform/webform.element.signature']],
-        ];
+        ] : '[' . $this->t('not valid') . ']';
 
       default:
         return parent::formatHtmlItem($element, $webform_submission, $options);
@@ -314,6 +316,11 @@ protected function getImageUrl(array $element, WebformSubmissionInterface $webfo
       return '';
     }
 
+    // Make sure existing signature values are valid.
+    if (!WebformSignatureElement::isSignatureValid($value)) {
+      return '';
+    }
+
     $webform = $webform_submission->getWebform();
     $element_key = $element['#webform_key'];
     $sid = $webform_submission->id();
@@ -332,7 +339,15 @@ protected function getImageUrl(array $element, WebformSubmissionInterface $webfo
       $image_directory = $image_submission_directory;
     }
 
-    $image_hash = Crypt::hmacBase64($value, Settings::getHashSalt());
+    // If a signature file was already created and shared using an
+    // unsafe image hash, then return it.
+    $unsafe_image_hash = Crypt::hmacBase64($value, Settings::getHashSalt());
+    $unsafe_image_uri = "$image_directory/signature-$unsafe_image_hash.png";
+    if (file_exists($unsafe_image_uri)) {
+      return file_create_url($unsafe_image_uri);
+    }
+
+    $image_hash = Crypt::hmacBase64('webform-signature-' . $value, Settings::getHashSalt());
     $image_uri = "$image_directory/signature-$image_hash.png";
 
     if (!file_exists($image_uri)) {
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformTable.php b/web/modules/webform/src/Plugin/WebformElement/WebformTable.php
new file mode 100644
index 0000000000..bd95181be0
--- /dev/null
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformTable.php
@@ -0,0 +1,272 @@
+<?php
+
+namespace Drupal\webform\Plugin\WebformElement;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\Element;
+use Drupal\webform\Plugin\WebformElementBase;
+use Drupal\webform\WebformInterface;
+use Drupal\webform\WebformSubmissionInterface;
+
+/**
+ * Provides a 'webform_table' element.
+ *
+ * @WebformElement(
+ *   id = "webform_table",
+ *   label = @Translation("Table"),
+ *   description = @Translation("Provides an element to render a table."),
+ *   category = @Translation("Containers"),
+ * )
+ */
+class WebformTable extends WebformElementBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineDefaultProperties() {
+    $properties = parent::defineDefaultProperties() + [
+      'title' => [],
+      'header' => [],
+      'caption' => '',
+      'sticky' => FALSE,
+      'prefix_children' => TRUE,
+    ];
+    unset(
+      $properties['format_items'],
+      $properties['format_items_html'],
+      $properties['format_items_text'],
+      $properties['unique'],
+      $properties['unique_user'],
+      $properties['unique_entity'],
+      $properties['unique_error'],
+      $properties['disabled'],
+      $properties['prepopulate']
+    );
+    return $properties;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineTranslatableProperties() {
+    return array_merge(parent::defineTranslatableProperties(), ['header']);
+  }
+
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isInput(array $element) {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isContainer(array $element) {
+    return TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepare(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
+    $this->prepareTableHeader($element);
+    parent::prepare($element, $webform_submission);
+  }
+
+  /**
+   * Prepare webform talble header for rendering.
+   *
+   * @param array &$element
+   *   A webform table element.
+   */
+  protected function prepareTableHeader(array &$element) {
+    // Convert webform table header into a simple table header.
+    if (!isset($element['#header'])) {
+      return;
+    }
+
+    foreach ($element['#header'] as $index => $header) {
+      if (is_array($header) && isset($header['title'])) {
+        $attributes = (isset($header['attributes'])) ? $header['attributes'] : [];
+        $element['#header'][$index] = [
+          'data' => ['#markup' => $header['title']],
+        ] + $attributes;
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getItemDefaultFormat() {
+    return 'table';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getItemFormats() {
+    return [
+      'table' => $this->t('Table'),
+      'fieldset' => $this->t('Fieldset'),
+      'details' => $this->t('Details (opened)'),
+      'details-closed' => $this->t('Details (closed)'),
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTestValues(array $element, WebformInterface $webform, array $options = []) {
+    return NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function format($type, array &$element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    $item_function = 'format' . $type . 'Item';
+    return $this->$item_function($element, $webform_submission, $options);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function formatHtmlItem(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    $format = $this->getItemFormat($element);
+    switch ($format) {
+      case 'details':
+      case 'details-closed':
+      case 'fieldset':
+        $element['#type'] = 'container';
+        break;
+
+      case 'table':
+      default:
+        $this->prepareTableHeader($element);
+        // Switch submission display back to a Drupal table.
+        $element['#type'] = 'table';
+        unset($element['#states']);
+        break;
+    }
+
+    // Build each individual table row.
+    foreach ($element as $row_key => $row_element) {
+      if (Element::child($row_key)) {
+        $row_element_plugin = $this->elementManager->getElementInstance($row_element);
+        $element[$row_key] = $row_element_plugin->buildHtml($row_element, $webform_submission, $options);
+      }
+    }
+    return $element;
+
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function formatTextItem(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    /** @var \Drupal\webform\WebformSubmissionViewBuilderInterface $view_builder */
+    $view_builder = \Drupal::entityTypeManager()->getViewBuilder('webform_submission');
+    $children = $view_builder->buildElements($element, $webform_submission, $options, 'text');
+    if (empty($children)) {
+      return [];
+    }
+
+    $build = ['#prefix' => PHP_EOL];
+    if (!empty($element['#title'])) {
+      $build['title'] = [
+        '#markup' => $element['#title'],
+        '#suffix' => PHP_EOL,
+      ];
+      $build['divider'] = [
+        '#markup' => str_repeat('-', mb_strlen($element['#title'])),
+        '#suffix' => PHP_EOL,
+      ];
+    }
+    $build['children'] = $children;
+    return $build;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function form(array $form, FormStateInterface $form_state) {
+    $form = parent::form($form, $form_state);
+    $form['table'] = [
+      '#type' => 'fieldset',
+      '#title' => $this->t('Table settings'),
+    ];
+
+    $form['table']['header'] = [
+      '#title' => $this->t('Table header'),
+      '#type' => 'webform_multiple',
+      '#header' => [
+        'title' => ['data' => $this->t('Header title'), 'width' => '50%'],
+        'attributes' => ['data' => $this->t('Header attributes'), 'width' => '50%'],
+      ],
+      '#element' => [
+        'title' => [
+          '#type' => 'textfield',
+          '#title' => $this->t('Header title'),
+          '#error_no_message' => TRUE,
+        ],
+        'attributes' => [
+          '#type' => 'webform_codemirror',
+          '#mode' => 'yaml',
+          '#title' => $this->t('Header attributes (YAML)'),
+          '#decode_value' => TRUE,
+          '#error_no_message' => TRUE,
+        ],
+      ],
+    ];
+
+    $form['table']['caption'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Caption for the table'),
+      '#description' => $this->t('A title semantically associated with your table for increased accessibility.'),
+      '#maxlength' => 255,
+    ];
+
+    $form['table']['sticky'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Enable Drupal style "sticky" table headers (Javascript)'),
+      '#description' => $this->t("If checked, the table's header will remain visible as the user scrolls through the table."),
+      '#return_value' => TRUE,
+    ];
+
+    $form['table']['prefix_children'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t("Automatically prefix and increment the table's rows and elements"),
+      '#description' => $this->t("If checked, all rows and elements within the table will be prefixed with the table's element key and a  incremented numeric value. (i.e. table_01_first_name)"),
+      '#return_value' => TRUE,
+    ];
+
+    // Update #required label.
+    $form['validation']['required_container']['required']['#title'] .= ' <em>' . $this->t('(Display purposes only)') . '</em>';
+    $form['validation']['required_container']['required']['#description'] = $this->t('If checked, adds required indicator to the title, if visible. To require individual elements, also tick "Required" under each elements settings.');
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function preview() {
+    return [
+      '#type' => 'table',
+      '#header' => [
+        $this->t('Header 1'),
+        $this->t('Header 2'),
+      ],
+      '#rows' => [
+        ['Row 1 - Col 1', 'Row 1 - Col 2'],
+        ['Row 2 - Col 1', 'Row 2 - Col 2'],
+        ['Row 3 - Col 1', 'Row 3 - Col 2'],
+      ],
+    ];
+  }
+
+}
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformTableRow.php b/web/modules/webform/src/Plugin/WebformElement/WebformTableRow.php
new file mode 100644
index 0000000000..e2d4e61335
--- /dev/null
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformTableRow.php
@@ -0,0 +1,420 @@
+<?php
+
+namespace Drupal\webform\Plugin\WebformElement;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\Element;
+use Drupal\webform\Plugin\WebformElementBase;
+use Drupal\webform\Element\WebformMessage as WebformMessageElement;
+use Drupal\webform\WebformInterface;
+use Drupal\webform\WebformSubmissionInterface;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+
+/**
+ * Provides a 'webform_table_row' element.
+ *
+ * @WebformElement(
+ *   id = "webform_table_row",
+ *   label = @Translation("Table row"),
+ *   description = @Translation("Provides an element to render a table row."),
+ *   category = @Translation("Containers"),
+ *   hidden = TRUE,
+ * )
+ */
+class WebformTableRow extends WebformElementBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineDefaultProperties() {
+    $properties = [
+      'title' => '',
+      'attributes' => [],
+    ] + $this->defineDefaultBaseProperties();
+    unset(
+      $properties['prepopulate']
+    );
+    return $properties;
+  }
+
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isInput(array $element) {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isContainer(array $element) {
+    return TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getItemDefaultFormat() {
+    return '';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getItemFormats() {
+    return [''];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function build($format, array &$element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    $format_function = 'format' . ucfirst($format);
+    return $this->$format_function($element, $webform_submission, $options);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildHtml(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    $webform = $webform_submission->getWebform();
+    $parent_key = $element['#webform_parent_key'];
+    $parent_element = $webform->getElement($parent_key);
+    $parent_format = (isset($parent_element['#format'])) ? $parent_element['#format'] : 'table';
+
+    // Remove #states.
+    unset($element['#states']);
+
+    switch ($parent_format) {
+      case 'details-closed':
+      case 'details':
+      case 'fieldset':
+        $webform_plugin_id = ($parent_format === 'details-closed') ? 'details' : $parent_format;
+        $element['#webform_plugin_id'] = $webform_plugin_id;
+        $element['#type'] = $webform_plugin_id;
+        $element['#format_item'] = $parent_format;
+        $element_plugin = $this->elementManager->getElementInstance($element);
+        return $element_plugin->buildHtml($element, $webform_submission, $options);
+
+      case 'table':
+      default:
+        foreach ($element as $column_key => $column_element) {
+          if (Element::property($column_key)) {
+            continue;
+          }
+
+          $column_element_plugin = $this->elementManager->getElementInstance($column_element);
+          if ($column_element_plugin->isContainer($column_element)) {
+            $column_build = $column_element_plugin->buildHtml($column_element, $webform_submission, $options);
+            $element[$column_key] = ['data' => $column_build];
+          }
+          elseif (!$column_element_plugin->isInput($column_element)) {
+            $element[$column_key] = ['data' => $column_element];
+          }
+          else {
+            $column_value = $column_element_plugin->format('html', $column_element, $webform_submission, $options);
+            $element[$column_key] = (is_array($column_value))
+              ? ['data' => $column_value]
+              : ['data' => ['#markup' => $column_value]];
+          }
+        }
+        return $element;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function formatTextItem(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    /** @var \Drupal\webform\WebformSubmissionViewBuilderInterface $view_builder */
+    $view_builder = \Drupal::entityTypeManager()->getViewBuilder('webform_submission');
+    $children = $view_builder->buildElements($element, $webform_submission, $options, 'text');
+    if (empty($children)) {
+      return [];
+    }
+
+    $build = [];
+    if (!empty($element['#title'])) {
+      $build['title'] = [
+        '#markup' => $element['#title'],
+        '#suffix' => PHP_EOL,
+      ];
+      $build['divider'] = [
+        '#markup' => str_repeat('-', mb_strlen($element['#title'])),
+        '#suffix' => PHP_EOL,
+      ];
+    }
+    $build['children'] = $children;
+    return $build;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTestValues(array $element, WebformInterface $webform, array $options = []) {
+    return NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function form(array $form, FormStateInterface $form_state) {
+    $form = parent::form($form, $form_state);
+
+    /** @var \Drupal\webform_ui\Form\WebformUiElementFormInterface $form_object */
+    $form_object = $form_state->getFormObject();
+
+    // Handle new row being added to a table.
+    if ($form_object->isNew()) {
+      $parent_key = $form_object->getParentKey();
+
+      // Make sure the new row is being inserted into a table.
+      $table_element = $form_object->getWebform()->getElement($parent_key);
+      if (!$table_element || $table_element['#type'] !== 'webform_table') {
+        throw new NotFoundHttpException();
+      }
+
+      // Make sure the table support prefixing.
+      $prefix_children = (!isset($table_element['#prefix_children']) || $table_element['#prefix_children'] === TRUE);
+      if (!$prefix_children) {
+        return $form;
+      }
+
+      $form['element']['table_message'] = [
+        '#type' => 'webform_message',
+        '#message_message' => $this->t("Row keys are the tables's key with an incremented value."),
+        '#message_type' => 'warning',
+        '#message_close' => TRUE,
+        '#message_storage' => WebformMessageElement::STORAGE_SESSION,
+        '#weight' => -98,
+        '#access' => TRUE,
+      ];
+
+      $element_properties = $form_state->get('element_properties');
+
+      // Set duplicate and incremented title element properties.
+      if ($table_element['#webform_children']) {
+        $first_row_key = reset($table_element['#webform_children']);
+        $first_row_element = $this->getWebform()->getElement($first_row_key);
+
+        if ($this->hasIncrementalChildrenElements($first_row_key)) {
+          $form['table_settings'] = [
+            '#type' => 'fieldset',
+            '#title' => $this->t('Table row settings'),
+          ];
+          $form['table_settings']['duplicate'] = [
+            '#type' => 'checkbox',
+            '#title' => $this->t("Duplicate the table's first row"),
+            '#return_value' => TRUE,
+          ];
+
+          $element_properties['duplicate'] = TRUE;
+        }
+        $element_properties['title'] = preg_replace(
+          '/\d+/',
+          $this->getNextIncrement(),
+          $first_row_element['#title']
+        );
+      }
+      else {
+        $element_properties['title'] = $table_element['#title'] . ' (1)';
+      }
+      $form_state->set('element_properties', $element_properties);
+    }
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDefaultKey() {
+    $webform = $this->getWebform();
+    $parent_key = \Drupal::request()->query->get('parent');
+    $table_element = $webform->getElement($parent_key);
+
+    // Make sure prefixing elements is enabled for the table.
+    $prefix_children = (!isset($table_element['#prefix_children']) || $table_element['#prefix_children'] === TRUE);
+    if (!$prefix_children) {
+      return NULL;
+    }
+
+    // Return the first rows keys based on the parent title.
+    if (empty($table_element['#webform_children'])) {
+      return $parent_key . '_01';
+    }
+
+    // Replace increment in first row.
+    $first_row_key = reset($table_element['#webform_children']);
+    $increment = $this->getNextIncrement();
+    $increment = str_pad($increment, 2, '0', STR_PAD_LEFT);
+    return preg_replace('/\d+/', $increment, $first_row_key);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigurationFormProperties(array &$form, FormStateInterface $form_state) {
+    $properties = parent::getConfigurationFormProperties($form, $form_state);
+
+    /** @var \Drupal\webform_ui\Form\WebformUiElementFormInterface $form_object */
+    $form_object = $form_state->getFormObject();
+    if (!$form_object->isNew()) {
+      return $properties;
+    }
+
+    // Get and unset the #duplicate property.
+    $duplicate = !empty($properties['#duplicate']);
+    unset($properties['#duplicate']);
+
+    // If $duplicate is FALSE don't duplicate the child elements.
+    if (!$duplicate) {
+      return $properties;
+    }
+
+    // This is the only way to get the row key for a new element.
+    $key = $_POST['key'];
+    $parent_key = \Drupal::request()->query->get('parent');
+    if (!$form_object->isNew() || !$parent_key) {
+      return $properties;
+    }
+
+    $row_index = (preg_match('/\d+/', $key, $match)) ? intval($match[0]) : NULL;
+    $table_element = $this->getWebform()->getElement($parent_key);
+    if (!$table_element['#webform_children']) {
+      return $properties;
+    }
+
+    $row_key = reset($table_element['#webform_children']);
+    $children_elements = $this->getChildrenElements($row_key, $row_index);
+    if ($children_elements === FALSE) {
+      $this->messenger()->addWarning("Unable to append child elements from @row because a child element's key do not include any index/number.", ['@row' => $row_key]);
+    }
+    else {
+      $properties += $children_elements;
+    }
+
+    return $properties;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementSelectorOptions(array $element) {
+    return [];
+  }
+
+  /****************************************************************************/
+  // Helper function.
+  /****************************************************************************/
+
+  /**
+   * Get the parent table's next row increment.
+   *
+   * @return int
+   *   The parent table's next row increment.
+   */
+  protected function getNextIncrement() {
+    $webform = $this->getWebform();
+    $parent_key = \Drupal::request()->query->get('parent');
+    $table_element = $webform->getElement($parent_key);
+
+    if (!$table_element['#webform_children']) {
+      return 1;
+    }
+
+    // Get next row increment.
+    $indexes = [];
+    foreach ($table_element['#webform_children'] as $child_key) {
+      preg_match('/\d+/', $child_key, $match);
+      $indexes[] = intval($match[0]);
+    }
+    return (max($indexes) + 1);
+  }
+
+  /**
+   * Determine if an element and its use incremental keys.
+   *
+   * @param string $key
+   *   An element key.
+   *
+   * @return bool
+   *   TRUE if an element and its use incremental keys.
+   */
+  protected function hasIncrementalChildrenElements($key) {
+    // Return FALSE if the key is not incremental.
+    if (!preg_match('/\d+/', $key, $match)) {
+      return FALSE;
+    }
+
+    $element = $this->getWebform()->getElement($key);
+    foreach ($element['#webform_children'] as $child_key) {
+      // Return FALSE if any child element key is not incremental.
+      if (!$this->hasIncrementalChildrenElements($child_key)) {
+        return FALSE;
+      }
+    }
+
+    return TRUE;
+  }
+
+  /**
+   * Get child elements incremented with a new index.
+   *
+   * @param string $element_key
+   *   The element key.
+   * @param int $index
+   *   The index for all child elements.
+   *
+   * @return array|bool
+   *   Child elements or FALSE is child element keys are not incremental.
+   */
+  protected function getChildrenElements($element_key, $index) {
+    $webform = $this->getWebform();
+    $element = $webform->getElement($element_key);
+
+    $elements = [];
+    foreach ($element['#webform_children'] as $child_key) {
+      // Return FALSE if the child key is not incremental.
+      if (!preg_match('/\d+/', $child_key, $match)) {
+        return FALSE;
+      }
+
+      // Set incremented key.
+      $increment = str_pad($index, 2, '0', STR_PAD_LEFT);
+      $increment_key = preg_replace('/\d+/', $increment, $child_key);
+
+      // Return FALSE if the sub element already exists.
+      if ($webform->getElement($increment_key)) {
+        return FALSE;
+      }
+
+      // Get the decoded element.
+      $element = $webform->getElementDecoded($child_key);
+
+      // Increment the element's #title and #admin_title.
+      $increment_properties = ['#title', '#admin_title'];
+      foreach ($increment_properties as $increment_property) {
+        if (isset($element[$increment_property])) {
+          $element[$increment_property] = preg_replace('/\d+/', $index, $element[$increment_property]);
+        }
+      }
+
+      // Get child elements.
+      $child_elements = $this->getChildrenElements($child_key, $index);
+
+      // Return FALSE if any child element is not incremented.
+      if ($child_elements === FALSE) {
+        return FALSE;
+      }
+
+      // Set new incremented element with child elements.
+      $elements[$increment_key] = $element + $child_elements;
+    }
+
+    return $elements;
+  }
+
+}
diff --git a/web/modules/webform/src/Plugin/WebformElementBase.php b/web/modules/webform/src/Plugin/WebformElementBase.php
index 907fa0fd14..fa0f88e8ae 100644
--- a/web/modules/webform/src/Plugin/WebformElementBase.php
+++ b/web/modules/webform/src/Plugin/WebformElementBase.php
@@ -1653,7 +1653,7 @@ protected function formatHtmlItem(array $element, WebformSubmissionInterface $we
     $value = $this->formatTextItem($element, $webform_submission, ['prefixing' => FALSE] + $options);
 
     if ($format === 'raw') {
-      return Markup::create($value);
+      return $value;
     }
 
     // Build a render that used #plain_text so that HTML characters are escaped.
diff --git a/web/modules/webform/src/Plugin/WebformElementBase.php.orig b/web/modules/webform/src/Plugin/WebformElementBase.php.orig
new file mode 100644
index 0000000000..907fa0fd14
--- /dev/null
+++ b/web/modules/webform/src/Plugin/WebformElementBase.php.orig
@@ -0,0 +1,3700 @@
+<?php
+
+namespace Drupal\webform\Plugin;
+
+use Drupal\Component\Plugin\PluginBase;
+use Drupal\Component\Utility\NestedArray;
+use Drupal\Component\Utility\Xss;
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Form\OptGroup;
+use Drupal\Core\Link;
+use Drupal\Core\Messenger\MessengerTrait;
+use Drupal\Core\Render\Element;
+use Drupal\Core\Render\ElementInfoManagerInterface;
+use Drupal\Core\Render\Markup;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\Core\Url;
+use Drupal\webform\Element\WebformCompositeFormElementTrait;
+use Drupal\webform\Element\WebformHtmlEditor;
+use Drupal\webform\Element\WebformMessage;
+use Drupal\webform\Entity\WebformOptions;
+use Drupal\webform\Plugin\WebformElement\Checkbox;
+use Drupal\webform\Plugin\WebformElement\Checkboxes;
+use Drupal\webform\Plugin\WebformElement\ContainerBase;
+use Drupal\webform\Plugin\WebformElement\Details;
+use Drupal\webform\Plugin\WebformElement\WebformCompositeBase;
+use Drupal\webform\Twig\WebformTwigExtension;
+use Drupal\webform\Utility\WebformArrayHelper;
+use Drupal\webform\Utility\WebformElementHelper;
+use Drupal\webform\Utility\WebformFormHelper;
+use Drupal\webform\Utility\WebformHtmlHelper;
+use Drupal\webform\Utility\WebformOptionsHelper;
+use Drupal\webform\Utility\WebformReflectionHelper;
+use Drupal\webform\WebformInterface;
+use Drupal\webform\WebformLibrariesManagerInterface;
+use Drupal\webform\WebformSubmissionConditionsValidator;
+use Drupal\webform\WebformSubmissionInterface;
+use Drupal\webform\WebformTokenManagerInterface;
+use Psr\Log\LoggerInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides a base class for a webform element.
+ *
+ * @see \Drupal\webform\Plugin\WebformElementInterface
+ * @see \Drupal\webform\Plugin\WebformElementManager
+ * @see \Drupal\webform\Plugin\WebformElementManagerInterface
+ * @see plugin_api
+ */
+class WebformElementBase extends PluginBase implements WebformElementInterface {
+
+  use StringTranslationTrait;
+  use MessengerTrait;
+  use WebformCompositeFormElementTrait;
+  use WebformEntityInjectionTrait;
+
+  /**
+   * A logger instance.
+   *
+   * @var \Psr\Log\LoggerInterface
+   */
+  protected $logger;
+
+  /**
+   * The configuration factory.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $configFactory;
+
+  /**
+   * The current user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $currentUser;
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * A element info manager.
+   *
+   * @var \Drupal\Core\Render\ElementInfoManagerInterface
+   */
+  protected $elementInfo;
+
+  /**
+   * The webform element manager.
+   *
+   * @var \Drupal\webform\Plugin\WebformElementManagerInterface
+   */
+  protected $elementManager;
+
+  /**
+   * The token manager.
+   *
+   * @var \Drupal\webform\WebformTokenManagerInterface
+   */
+  protected $tokenManager;
+
+  /**
+   * The libraries manager.
+   *
+   * @var \Drupal\webform\WebformLibrariesManagerInterface
+   */
+  protected $librariesManager;
+
+  /**
+   * The webform submission storage.
+   *
+   * @var \Drupal\webform\WebformSubmissionStorageInterface
+   */
+  protected $submissionStorage;
+
+  /**
+   * An associative array of an element's default properties names and values.
+   *
+   * @var array
+   */
+  protected $defaultProperties;
+
+  /**
+   * An indexed array of an element's translated properties.
+   *
+   * @var array
+   */
+  protected $translatableProperties;
+
+  /**
+   * Constructs a WebformElementBase object.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Psr\Log\LoggerInterface $logger
+   *   A logger instance.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The configuration factory.
+   * @param \Drupal\Core\Session\AccountInterface $current_user
+   *   The current user.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   * @param \Drupal\Core\Render\ElementInfoManagerInterface $element_info
+   *   The element info manager.
+   * @param \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager
+   *   The webform element manager.
+   * @param \Drupal\webform\WebformTokenManagerInterface $token_manager
+   *   The webform token manager.
+   * @param \Drupal\webform\WebformLibrariesManagerInterface $libraries_manager
+   *   The webform libraries manager.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, LoggerInterface $logger, ConfigFactoryInterface $config_factory, AccountInterface $current_user, EntityTypeManagerInterface $entity_type_manager, ElementInfoManagerInterface $element_info, WebformElementManagerInterface $element_manager, WebformTokenManagerInterface $token_manager, WebformLibrariesManagerInterface $libraries_manager) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+    $this->logger = $logger;
+    $this->configFactory = $config_factory;
+    $this->currentUser = $current_user;
+    $this->entityTypeManager = $entity_type_manager;
+    $this->elementInfo = $element_info;
+    $this->elementManager = $element_manager;
+    $this->tokenManager = $token_manager;
+    $this->librariesManager = $libraries_manager;
+    $this->submissionStorage = $entity_type_manager->getStorage('webform_submission');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('logger.factory')->get('webform'),
+      $container->get('config.factory'),
+      $container->get('current_user'),
+      $container->get('entity_type.manager'),
+      $container->get('plugin.manager.element_info'),
+      $container->get('plugin.manager.webform.element'),
+      $container->get('webform.token_manager'),
+      $container->get('webform.libraries_manager')
+    );
+  }
+
+  /****************************************************************************/
+  // Property definitions.
+  /****************************************************************************/
+
+  /**
+   * Define an element's default properties.
+   *
+   * @return array
+   *   An associative array contain an the element's default properties.
+   */
+  protected function defineDefaultProperties() {
+    $properties = [
+      // Element settings.
+      'title' => '',
+      'default_value' => '',
+      // Description/Help.
+      'help' => '',
+      'help_title' => '',
+      'description' => '',
+      'more' => '',
+      'more_title' => '',
+      // Form display.
+      'title_display' => '',
+      'description_display' => '',
+      'help_display' => '',
+      'field_prefix' => '',
+      'field_suffix' => '',
+      'disabled' => FALSE,
+      // Form validation.
+      'required' => FALSE,
+      'required_error' => '',
+      // Attributes.
+      'wrapper_attributes' => [],
+      'label_attributes' => [],
+      'attributes' => [],
+      // Submission display.
+      'format' => $this->getItemDefaultFormat(),
+      'format_html' => '',
+      'format_text' => '',
+      'format_items' => $this->getItemsDefaultFormat(),
+      'format_items_html' => '',
+      'format_items_text' => '',
+      'format_attributes' => [],
+    ];
+
+    // Unique validation.
+    if (!$this->isComposite()) {
+      $properties += [
+        'unique' => FALSE,
+        'unique_user' => FALSE,
+        'unique_entity' => FALSE,
+        'unique_error' => '',
+      ];
+    }
+
+    $properties += $this->defineDefaultBaseProperties();
+
+    return $properties;
+  }
+
+  /**
+   * Define default multiple properties used by most elements.
+   *
+   * @return array
+   *   An associative array containing default multiple properties.
+   */
+  protected function defineDefaultMultipleProperties() {
+    return [
+      'multiple' => FALSE,
+      'multiple__header_label' => '',
+      'multiple__min_items' => NULL,
+      'multiple__empty_items' => 1,
+      'multiple__add_more' => TRUE,
+      'multiple__add_more_items' => 1,
+      'multiple__add_more_button_label' => (string) $this->t('Add'),
+      'multiple__add_more_input' => TRUE,
+      'multiple__add_more_input_label' => (string) $this->t('more items'),
+      'multiple__no_items_message' => (string) $this->t('No items entered. Please add items below.'),
+      'multiple__sorting' => TRUE,
+      'multiple__operations' => TRUE,
+    ];
+  }
+
+  /**
+   * Define default base properties used by all elements.
+   *
+   * @return array
+   *   An associative array containing base properties used by all elements.
+   */
+  protected function defineDefaultBaseProperties() {
+    return [
+      // Administration.
+      'admin_title' => '',
+      'prepopulate' => FALSE,
+      'private' => FALSE,
+      // Flexbox.
+      'flex' => 1,
+      // Conditional logic.
+      'states' => [],
+      'states_clear' => TRUE,
+      // Element access.
+      'access_create_roles' => ['anonymous', 'authenticated'],
+      'access_create_users' => [],
+      'access_create_permissions' => [],
+      'access_update_roles' => ['anonymous', 'authenticated'],
+      'access_update_users' => [],
+      'access_update_permissions' => [],
+      'access_view_roles' => ['anonymous', 'authenticated'],
+      'access_view_users' => [],
+      'access_view_permissions' => [],
+    ];
+  }
+
+  /**
+   * Define an element's translatable properties.
+   *
+   * @return array
+   *   An array containing an element's translatable properties.
+   */
+  protected function defineTranslatableProperties() {
+    return [
+      'title',
+      'label',
+      'help',
+      'help_title',
+      'more',
+      'more_title',
+      'description',
+      'field_prefix',
+      'field_suffix',
+      'required_error',
+      'unique_error',
+      'admin_title',
+      'placeholder',
+      'markup',
+      'test',
+      'default_value',
+      'header_label',
+      'add_more_button_label',
+      'add_more_input_label',
+      'no_items_message',
+    ];
+  }
+
+  /****************************************************************************/
+  // Property methods.
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDefaultProperties() {
+    if (!isset($this->defaultProperties)) {
+      $properties = $this->defineDefaultProperties();
+      $definition = $this->getPluginDefinition();
+      \Drupal::moduleHandler()->alter(
+        'webform_element_default_properties',
+        $properties,
+        $definition
+      );
+      $this->defaultProperties = $properties;
+    }
+    return $this->defaultProperties;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTranslatableProperties() {
+    if (!isset($this->translatableProperties)) {
+      $properties = $this->defineTranslatableProperties();
+      $definition = $this->getPluginDefinition();
+      \Drupal::moduleHandler()->alter(
+        'webform_element_translatable_properties',
+        $properties,
+        $definition
+      );
+      $this->translatableProperties = array_unique($properties);
+    }
+    return $this->translatableProperties;
+  }
+
+  /**
+   * Get default multiple properties used by most elements.
+   *
+   * @return array
+   *   An associative array containing default multiple properties.
+   *
+   * @deprecated Scheduled for removal in Webform 8.x-6.x
+   *   Use \Drupal\webform\Plugin\WebformElementBase::defineDefaultBaseProperties instead.
+   */
+  protected function getDefaultMultipleProperties() {
+    @trigger_error('\Drupal\webform\Plugin\WebformElementBase::getDefaultMultipleProperties is scheduled for removal in Webform 8.x-6.x. Use \Drupal\webform\Plugin\WebformElementBase::defineDefaultBaseProperties instead.', E_USER_DEPRECATED);
+    return $this->defineDefaultBaseProperties();
+  }
+
+  /**
+   * Get default base properties used by all elements.
+   *
+   * @return array
+   *   An associative array containing base properties used by all elements.
+   *
+   * @deprecated Scheduled for removal in Webform 8.x-6.x
+   *   Use \Drupal\webform\Plugin\WebformElementBase::defineDefaultBaseProperties instead.
+   */
+  protected function getDefaultBaseProperties() {
+    @trigger_error('\Drupal\webform\Plugin\WebformElementBase::getDefaultBaseProperties is scheduled for removal in Webform 8.x-6.x. Use \Drupal\webform\Plugin\WebformElementBase::defineDefaultBaseProperties instead.', E_USER_DEPRECATED);
+    return $this->defineDefaultBaseProperties();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasProperty($property_name) {
+    $default_properties = $this->getDefaultProperties();
+    return array_key_exists($property_name, $default_properties);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDefaultProperty($property_name) {
+    $default_properties = $this->getDefaultProperties();
+    return (array_key_exists($property_name, $default_properties)) ? $default_properties[$property_name] : NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementProperty(array $element, $property_name) {
+    return (isset($element["#$property_name"])) ? $element["#$property_name"] : $this->getDefaultProperty($property_name);
+  }
+
+  /**
+   * Set element's default callback.
+   *
+   * This makes sure that an element's default callback is not clobbered by
+   * any additional callbacks.
+   *
+   * @param array $element
+   *   A render element.
+   * @param string $callback_name
+   *   A render element's callback.
+   */
+  protected function setElementDefaultCallback(array &$element, $callback_name) {
+    $callback_name = ($callback_name[0] !== '#') ? '#' . $callback_name : $callback_name;
+    $callback_value = $this->getElementInfoDefaultProperty($element, $callback_name) ?: [];
+    if (!empty($element[$callback_name])) {
+      $element[$callback_name] = array_merge($callback_value, $element[$callback_name]);
+    }
+    else {
+      $element[$callback_name] = $callback_value;
+    }
+  }
+
+  /**
+   * Get a render element's default property.
+   *
+   * @param array $element
+   *   A render element.
+   * @param string $property_name
+   *   An element's property name.
+   *
+   * @return mixed
+   *   A render element's default value, or NULL if
+   *   property does not exist.
+   */
+  protected function getElementInfoDefaultProperty(array $element, $property_name) {
+    if (!isset($element['#type'])) {
+      return NULL;
+    }
+    $property_name = ($property_name[0] !== '#') ? '#' . $property_name : $property_name;
+    $type = $element['#type'];
+    return $this->elementInfo->getInfoProperty($type, $property_name, NULL)
+      ?: $this->elementInfo->getInfoProperty("webform_$type", $property_name, NULL);
+  }
+
+  /****************************************************************************/
+  // Definition and meta data methods.
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormElementClassDefinition() {
+    $definition = $this->elementInfo->getDefinition($this->getBaseId());
+    return $definition['class'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPluginApiUrl() {
+    return (!empty($this->pluginDefinition['api'])) ? Url::fromUri($this->pluginDefinition['api']) : NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPluginApiLink() {
+    $api_url = $this->getPluginApiUrl();
+    return ($api_url) ? Link::fromTextAndUrl($this->getPluginLabel(), $api_url) : NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPluginLabel() {
+    return $this->pluginDefinition['label'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPluginDescription() {
+    return $this->pluginDefinition['description'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPluginCategory() {
+    return $this->pluginDefinition['category'] ?: $this->t('Other elements');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTypeName() {
+    return $this->pluginDefinition['id'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDefaultKey() {
+    return (isset($this->pluginDefinition['default_key'])) ? $this->pluginDefinition['default_key'] : NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isInput(array $element) {
+    return (!empty($element['#type'])) ? TRUE : FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasWrapper(array $element) {
+    return $this->hasProperty('wrapper_attributes');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isContainer(array $element) {
+    return ($this->isInput($element)) ? FALSE : TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isRoot() {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasManagedFiles(array $element) {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function supportsMultipleValues() {
+    return $this->hasProperty('multiple');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasMultipleWrapper() {
+    return TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasMultipleValues(array $element) {
+    if ($this->hasProperty('multiple')) {
+      if (isset($element['#multiple'])) {
+        return $element['#multiple'];
+      }
+      else {
+        $default_property = $this->getDefaultProperties();
+        return $default_property['multiple'];
+      }
+    }
+    else {
+      return FALSE;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isMultiline(array $element) {
+    $item_format = $this->getItemFormat($element);
+    $items_format = $this->getItemsFormat($element);
+
+    // Check is multi value element.
+    if ($this->hasMultipleValues($element) && in_array($items_format, ['ol', 'ul', 'hr', 'custom'])) {
+      return TRUE;
+    }
+
+    // Check if custom items template has HTML block tags.
+    if ($items_format == 'custom' && isset($element['#format_items_html']) && WebformHtmlHelper::hasBlockTags($element['#format_items_html'])) {
+      return TRUE;
+    }
+
+    // Check if custom item template has HTML block tags.
+    if ($item_format == 'custom' && isset($element['#format_html']) && WebformHtmlHelper::hasBlockTags($element['#format_html'])) {
+      return TRUE;
+    }
+
+    return $this->pluginDefinition['multiline'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isComposite() {
+    return $this->pluginDefinition['composite'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isHidden() {
+    return $this->pluginDefinition['hidden'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isExcluded() {
+    return $this->configFactory->get('webform.settings')->get('element.excluded_elements.' . $this->pluginDefinition['id']) ? TRUE : FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isEnabled() {
+    return !$this->isExcluded();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isDisabled() {
+    return !$this->isEnabled();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getInfo() {
+    return $this->elementInfo->getInfo($this->getBaseId());
+  }
+
+  /****************************************************************************/
+  // Element relationship methods.
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRelatedTypes(array $element) {
+    $types = [];
+
+    $parent_classes = WebformReflectionHelper::getParentClasses($this, 'WebformElementBase');
+
+    $plugin_id = $this->getPluginId();
+    $is_container = $this->isContainer($element);
+    $has_multiple_values = $this->hasMultipleValues($element);
+    $is_multiline = $this->isMultiline($element);
+
+    $elements = $this->elementManager->getInstances();
+    foreach ($elements as $element_name => $element_instance) {
+      // Skip self.
+      if ($plugin_id == $element_instance->getPluginId()) {
+        continue;
+      }
+
+      // Skip disabled or hidden.
+      if ($element_instance->isDisabled() || $element_instance->isHidden()) {
+        continue;
+      }
+
+      // Compare element base (abstract) class.
+      $element_instance_parent_classes = WebformReflectionHelper::getParentClasses($element_instance, 'WebformElementBase');
+      if ($parent_classes[1] != $element_instance_parent_classes[1]) {
+        continue;
+      }
+
+      // Compare container, supports/has multiple values, and multiline.
+      if ($is_container != $element_instance->isContainer($element)) {
+        continue;
+      }
+      if ($has_multiple_values != $element_instance->hasMultipleValues($element)) {
+        continue;
+      }
+      if ($is_multiline != $element_instance->isMultiline($element)) {
+        continue;
+      }
+
+      $types[$element_name] = $element_instance->getPluginLabel();
+    }
+
+    asort($types);
+    return $types;
+  }
+
+  /****************************************************************************/
+  // Element rendering methods.
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function initialize(array &$element) {
+    // Set element options.
+    if (isset($element['#options'])) {
+      $element['#options'] = WebformOptions::getElementOptions($element);
+    }
+
+    // Set #admin_title to #title without any HTML markup.
+    if (!empty($element['#title']) && empty($element['#admin_title'])) {
+      $element['#admin_title'] = strip_tags($element['#title']);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepare(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
+    $attributes_property = ($this->hasWrapper($element)) ? '#wrapper_attributes' : '#attributes';
+    if ($webform_submission) {
+      // Add webform and webform_submission IDs to every element.
+      $element['#webform'] = $webform_submission->getWebform()->id();
+      $element['#webform_submission'] = $webform_submission->id();
+
+      // Check is the element is disabled and hide it.
+      if ($this->isDisabled()) {
+        if ($webform_submission->getWebform()->access('edit')) {
+          $this->displayDisabledWarning($element);
+        }
+        $element['#access'] = FALSE;
+      }
+
+      // Apply element specific access rules.
+      $operation = ($webform_submission->isCompleted()) ? 'update' : 'create';
+      // Make sure the webform and submission is set before
+      // checking access rules.
+      $this->setEntities($webform_submission);
+      $element['#access'] = $this->checkAccessRules($operation, $element);
+    }
+
+    // Enable webform template preprocessing enhancements.
+    // @see \Drupal\webform\Utility\WebformElementHelper::isWebformElement
+    $element['#webform_element'] = TRUE;
+
+    // Add #allowed_tags.
+    $allowed_tags = $this->configFactory->get('webform.settings')->get('element.allowed_tags');
+    switch ($allowed_tags) {
+      case 'admin':
+        $element['#allowed_tags'] = Xss::getAdminTagList();
+        break;
+
+      case 'html':
+        $element['#allowed_tags'] = Xss::getHtmlTagList();
+        break;
+
+      default:
+        $element['#allowed_tags'] = preg_split('/ +/', $allowed_tags);
+        break;
+    }
+
+    // Add autocomplete attribute.
+    if (isset($element['#autocomplete'])) {
+      $element['#attributes']['autocomplete'] = $element['#autocomplete'];
+    }
+
+    // Add inline title display support.
+    // Inline fieldset layout is handled via webform_preprocess_fieldset().
+    // @see webform_preprocess_fieldset()
+    if (isset($element['#title_display']) && $element['#title_display'] == 'inline') {
+      // Store reference to unset #title_display.
+      $element['#_title_display'] = $element['#title_display'];
+      unset($element['#title_display']);
+      $element['#wrapper_attributes']['class'][] = 'webform-element--title-inline';
+    }
+
+    // Check markup properties.
+    $markup_properties = [
+      '#description',
+      '#help',
+      '#more',
+      '#multiple__no_items_message',
+    ];
+    foreach ($markup_properties as $markup_property) {
+      if (isset($element[$markup_property]) && !is_array($element[$markup_property])) {
+        $element[$markup_property] = WebformHtmlEditor::checkMarkup($element[$markup_property]);
+      }
+    }
+
+    // Add default description display.
+    $default_description_display = $this->configFactory->get('webform.settings')->get('element.default_description_display');
+    if ($default_description_display && !isset($element['#description_display']) && $this->hasProperty('description_display')) {
+      $element['#description_display'] = $default_description_display;
+    }
+
+    // Add tooltip description display support.
+    if (isset($element['#description_display']) && $element['#description_display'] === 'tooltip') {
+      $element['#description_display'] = 'invisible';
+      $element[$attributes_property]['class'][] = 'js-webform-tooltip-element';
+      $element[$attributes_property]['class'][] = 'webform-tooltip-element';
+      $element['#attached']['library'][] = 'webform/webform.tooltip';
+    }
+
+    // Add .webform-has-field-prefix and .webform-has-field-suffix class.
+    if (!empty($element['#field_prefix'])) {
+      $element[$attributes_property]['class'][] = 'webform-has-field-prefix';
+    }
+    if (!empty($element['#field_suffix'])) {
+      $element[$attributes_property]['class'][] = 'webform-has-field-suffix';
+    }
+
+    // Add 'data-webform-states-no-clear' attribute if #states_clear is FALSE.
+    if (isset($element['#states_clear']) && $element['#states_clear'] === FALSE) {
+      $element[$attributes_property]['data-webform-states-no-clear'] = TRUE;
+    }
+
+    // Set element's #element_validate callback so that is not replaced when
+    // we append additional #element_validate callbacks.
+    $this->setElementDefaultCallback($element, 'element_validate');
+    $this->prepareElementValidateCallbacks($element, $webform_submission);
+
+    if ($this->isInput($element)) {
+      // Handle #readonly support.
+      // @see \Drupal\Core\Form\FormBuilder::handleInputElement
+      if (!empty($element['#readonly'])) {
+        $element['#attributes']['readonly'] = 'readonly';
+        if ($this->hasProperty('wrapper_attributes')) {
+          $element['#wrapper_attributes']['class'][] = 'webform-readonly';
+        }
+      }
+
+      // Set custom required error message as 'data-required-error' attribute.
+      // @see Drupal.behaviors.webformRequiredError
+      // @see webform.form.js
+      if (!empty($element['#required_error'])) {
+        $element['#attributes']['data-webform-required-error'] = WebformHtmlHelper::toPlainText($element['#required_error']);
+        $element['#required_error'] = WebformHtmlHelper::toHtmlMarkup($element['#required_error']);
+      }
+    }
+
+    // Replace tokens for all properties.
+    if ($webform_submission) {
+      $this->replaceTokens($element, $webform_submission);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function finalize(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
+    // Set element's #element_validate callback so that is not replaced when
+    // we append additional #pre_render callbacks.
+    $this->setElementDefaultCallback($element, 'pre_render');
+    $this->prepareElementPreRenderCallbacks($element, $webform_submission);
+
+    // Prepare composite element.
+    $this->prepareCompositeFormElement($element);
+
+    // Prepare multiple element.
+    $this->prepareMultipleWrapper($element);
+
+    // Prepare #states and flexbox wrapper.
+    $this->prepareWrapper($element);
+
+    // Set hidden element #after_build handler.
+    $this->setElementDefaultCallback($element, 'after_build');
+    $element['#after_build'][] = [get_class($this), 'hiddenElementAfterBuild'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function alterForm(array &$element, array &$form, FormStateInterface $form_state) {
+    // Do nothing.
+  }
+
+  /**
+   * Webform element #after_build callback.
+   *
+   * Wrap #element_validate so that we suppress element validation errors.
+   */
+  public static function hiddenElementAfterBuild(array $element, FormStateInterface $form_state) {
+    if (!isset($element['#access']) || $element['#access']) {
+      return $element;
+    }
+
+    // Disabled #required validation for hidden elements.
+    $element['#required'] = FALSE;
+
+    return WebformElementHelper::setElementValidate($element);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function checkAccessRules($operation, array $element, AccountInterface $account = NULL) {
+    // Respect elements that already have their #access set to FALSE.
+    if (isset($element['#access']) && $element['#access'] === FALSE) {
+      return FALSE;
+    }
+
+    // Get the current user, webform, and webform submission.
+    $account = $account ?: $this->currentUser;
+    $webform = $this->getWebform();
+    $webform_submission = $this->getWebformSubmission();
+
+    // If webform is missing, throw an exception.
+    if (!$webform) {
+      throw new \Exception("Webform entity is required to check and element's access (rules).");
+    }
+
+    // If #private, check that the current user can 'view any submission'.
+    if (!empty($element['#private']) && !$webform->access('submission_view_any', $account)) {
+      return FALSE;
+    }
+
+    // Check webform and other modules access results.
+    $access_result = $this->checkAccessRule($element, $operation, $account)
+      ? AccessResult::allowed()
+      : AccessResult::neutral();
+
+    // Allow webform handlers to adjust the access and/or directly set an
+    // element's #access to FALSE.
+    $handler_result = $webform->invokeHandlers('accessElement', $element, $operation, $account, $webform_submission);
+    $access_result = $access_result->orIf($handler_result);
+
+    // Allow modules to adjust the element's access.
+    $context = [
+      'webform' => $webform,
+      'webform_submission' => $webform_submission,
+    ];
+    $modules = \Drupal::moduleHandler()
+      ->getImplementations('webform_element_access');
+    foreach ($modules as $module) {
+      $hook = $module . '_webform_element_access';
+      $hook_result = $hook($operation, $element, $account, $context);
+      $access_result = $access_result->orIf($hook_result);
+    }
+
+    // Grant access as provided by webform, webform handler(s) and/or
+    // hook_webform_element_access() implementation.
+    return $access_result->isAllowed();
+  }
+
+  /**
+   * Checks an access rule against a user account's roles and id.
+   *
+   * @param array $element
+   *   The element.
+   * @param string $operation
+   *   The operation.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The user session for which to check access.
+   *
+   * @return bool
+   *   The access result. Returns a TRUE if access is allowed.
+   *
+   * @see \Drupal\webform\Entity\Webform::checkAccessRule
+   */
+  protected function checkAccessRule(array $element, $operation, AccountInterface $account) {
+    // If no access rules are set return NULL (no opinion).
+    // @see \Drupal\webform\Plugin\WebformElementBase::defaultBaseProperties
+    if (!isset($element['#access_' . $operation . '_roles'])
+      && !isset($element['#access_' . $operation . '_users'])
+      && !isset($element['#access_' . $operation . '_permissions'])) {
+      return TRUE;
+    }
+
+    // If access roles are not set then use the anonymous and authenticated
+    // roles from the element's default properties.
+    // @see \Drupal\webform\Plugin\WebformElementBase::defaultBaseProperties
+    if (!isset($element['#access_' . $operation . '_roles'])) {
+      $element['#access_' . $operation . '_roles'] = $this->getDefaultProperty('access_' . $operation . '_roles') ?: [];
+    }
+    if (array_intersect($element['#access_' . $operation . '_roles'], $account->getRoles())) {
+      return TRUE;
+    }
+
+    if (isset($element['#access_' . $operation . '_users']) && in_array($account->id(), $element['#access_' . $operation . '_users'])) {
+      return TRUE;
+    }
+
+    if (isset($element['#access_' . $operation . '_permissions'])) {
+      foreach ($element['#access_' . $operation . '_permissions'] as $permission) {
+        if ($account->hasPermission($permission)) {
+          return TRUE;
+        }
+      }
+    }
+
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function replaceTokens(array &$element, EntityInterface $entity = NULL) {
+    foreach ($element as $key => $value) {
+      // Only replace tokens in properties.
+      if (Element::child($key)) {
+        continue;
+      }
+
+      // Ignore tokens in #template and #format_* properties.
+      if (in_array($key, ['#template', '#format_html', '#format_text', 'format_items_html', 'format_items_text'])) {
+        continue;
+      }
+
+      $element[$key] = $this->tokenManager->replaceNoRenderContext($value, $entity);
+    }
+  }
+
+  /**
+   * Prepare an element's validation callbacks.
+   *
+   * @param array $element
+   *   An element.
+   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
+   *   A webform submission.
+   */
+  protected function prepareElementValidateCallbacks(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
+    // Validation callbacks are only applicable to inputs.
+    if (!$this->isInput($element)) {
+      return;
+    }
+
+    // Add webform element #minlength, #multiple, and/or #unique
+    // validation handler.
+    if (isset($element['#minlength'])) {
+      $element['#element_validate'][] = [get_class($this), 'validateMinlength'];
+    }
+    if (isset($element['#multiple']) && $element['#multiple'] > 1) {
+      $element['#element_validate'][] = [get_class($this), 'validateMultiple'];
+    }
+    if (isset($element['#unique']) && $webform_submission) {
+      $element['#element_validate'][] = [get_class($this), 'validateUnique'];
+    }
+  }
+
+  /**
+   * Prepare an element's pre render callbacks.
+   *
+   * @param array $element
+   *   An element.
+   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
+   *   A webform submission.
+   */
+  protected function prepareElementPreRenderCallbacks(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
+    // Do nothing.
+  }
+
+  /**
+   * Replace Core's composite #pre_render with Webform's composite #pre_render.
+   *
+   * @param array $element
+   *   An element.
+   *
+   * @see \Drupal\Core\Render\Element\CompositeFormElementTrait
+   * @see \Drupal\webform\Element\WebformCompositeFormElementTrait
+   */
+  protected function prepareCompositeFormElement(array &$element) {
+    if (empty($element['#pre_render'])) {
+      return;
+    }
+
+    // Replace preRenderCompositeFormElement with
+    // preRenderWebformCompositeFormElement.
+    foreach ($element['#pre_render'] as $index => $pre_render) {
+      if (is_array($pre_render) && $pre_render[1] === 'preRenderCompositeFormElement') {
+        $element['#pre_render'][$index] = [get_called_class(), 'preRenderWebformCompositeFormElement'];
+      }
+    }
+  }
+
+  /**
+   * Set an elements #states and flexbox wrapper.
+   *
+   * @param array $element
+   *   An element.
+   */
+  protected function prepareWrapper(array &$element) {
+    $has_states_wrapper = $this->pluginDefinition['states_wrapper'];
+    $has_flexbox_wrapper = !empty($element['#webform_parent_flexbox']);
+    if (!$has_states_wrapper && !$has_flexbox_wrapper) {
+      return;
+    }
+
+    $class = get_class($this);
+
+    // Fix #states wrapper.
+    if ($has_states_wrapper) {
+      $element['#pre_render'][] = [$class, 'preRenderFixStatesWrapper'];
+    }
+
+    // Add flex(box) wrapper.
+    if ($has_flexbox_wrapper) {
+      $element['#pre_render'][] = [$class, 'preRenderFixFlexboxWrapper'];
+    }
+  }
+
+  /**
+   * Fix state wrapper.
+   *
+   * Notes:
+   * - Certain elements don't support #states so a workaround is to adds a
+   *   wrapper that renders the #states in a #prefix and #suffix div tag.
+   * - Composite elements tend not to properly handle #states.
+   * - Composite elements need propagate a visible/hidden #states to
+   *   sub-element required #state.
+   *
+   * @param array $element
+   *   An element.
+   *
+   * @return array
+   *   An element with #states added to the #prefix and #suffix.
+   */
+  public static function preRenderFixStatesWrapper(array $element) {
+    WebformElementHelper::fixStatesWrapper($element);
+    return $element;
+  }
+
+  /**
+   * Fix flexbox wrapper.
+   *
+   * @param array $element
+   *   An element.
+   *
+   * @return array
+   *   An element with flexbox wrapper added to the #prefix and #suffix.
+   */
+  public static function preRenderFixFlexboxWrapper(array $element) {
+    $flex = (isset($element['#flex'])) ? $element['#flex'] : 1;
+    $element += ['#prefix' => '', '#suffix' => ''];
+    $element['#prefix'] = '<div class="webform-flex webform-flex--' . $flex . '"><div class="webform-flex--container">' . $element['#prefix'];
+    $element['#suffix'] = $element['#suffix'] . '</div></div>';
+    return $element;
+  }
+
+  /**
+   * Set multiple element wrapper.
+   *
+   * @param array $element
+   *   An element.
+   */
+  protected function prepareMultipleWrapper(array &$element) {
+    if (!$this->hasMultipleValues($element) || !$this->hasMultipleWrapper() || empty($element['#multiple'])) {
+      return;
+    }
+
+    // Set the multiple element.
+    $element['#element'] = $element;
+
+    // Remove properties that should only be applied to the parent element.
+    $element['#element'] = array_diff_key($element['#element'], array_flip(['#access', '#default_value', '#description', '#description_display', '#required', '#required_error', '#states', '#wrapper_attributes', '#prefix', '#suffix', '#element', '#tags', '#multiple']));
+
+    // Propagate #states to sub element.
+    // @see \Drupal\webform\Element\WebformCompositeBase::processWebformComposite
+    if (!empty($element['#states'])) {
+      $element['#element']['#_webform_states'] = $element['#states'];
+    }
+
+    // Always make the title invisible.
+    $element['#element']['#title_display'] = 'invisible';
+
+    // Set hidden element #after_build handler.
+    $element['#element']['#after_build'][] = [get_class($this), 'hiddenElementAfterBuild'];
+
+    // Remove 'for' from the main element's label.
+    // This must be done after the $element['#element' is defined.
+    $element['#label_attributes']['webform-remove-for-attribute'] = TRUE;
+
+    // Change the element to a multiple element.
+    $element['#type'] = 'webform_multiple';
+    $element['#webform_multiple'] = TRUE;
+
+    // Set cardinality from #multiple.
+    if ($element['#multiple'] > 1) {
+      $element['#cardinality'] = $element['#multiple'];
+    }
+
+    // Apply multiple properties.
+    $multiple_properties = $this->defineDefaultMultipleProperties();
+    foreach ($multiple_properties as $multiple_property => $multiple_value) {
+      if (strpos($multiple_property, 'multiple__') === 0) {
+        $property_name = str_replace('multiple__', '', $multiple_property);
+        $element["#$property_name"] = (isset($element["#$multiple_property"])) ? $element["#$multiple_property"] : $multiple_value;
+      }
+    }
+
+    // If header label is defined use it for the #header.
+    if (!empty($element['#multiple__header_label'])) {
+      $element['#header'] = $element['#multiple__header_label'];
+    }
+
+    // Remove properties that should only be applied to the child element.
+    $element = array_diff_key($element, array_flip(['#attributes', '#field_prefix', '#field_suffix', '#pattern', '#placeholder', '#maxlength', '#element_validate', '#pre_render']));
+
+    // Apply #unique multiple validation.
+    if (isset($element['#unique'])) {
+      $element['#element_validate'][] = [get_class($this), 'validateUniqueMultiple'];
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function displayDisabledWarning(array $element) {
+    $t_args = [
+      '%title' => $this->getLabel($element),
+      '%type' => $this->getPluginLabel(),
+      ':href' => Url::fromRoute('webform.config.elements')->toString(),
+    ];
+    if ($this->currentUser->hasPermission('administer webform')) {
+      $message = $this->t('%title is a %type element, which has been disabled and will not be rendered. Go to the <a href=":href">admin settings</a> page to enable this element.', $t_args);
+    }
+    else {
+      $message = $this->t('%title is a %type element, which has been disabled and will not be rendered. Please contact a site administrator.', $t_args);
+    }
+    $this->messenger()->addWarning($message);
+
+    $context = [
+      '@title' => $this->getLabel($element),
+      '@type' => $this->getPluginLabel(),
+      'link' => Link::fromTextAndUrl($this->t('Edit'), Url::fromRoute('<current>'))->toString(),
+    ];
+    $this->logger->notice("'@title' is a '@type' element, which has been disabled and will not be rendered.", $context);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setDefaultValue(array &$element) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getLabel(array $element) {
+    return (!empty($element['#title'])) ? $element['#title'] : $element['#webform_key'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getAdminLabel(array $element) {
+    $element += ['#admin_title' => '', '#title' => '', '#webform_key' => ''];
+    return $element['#admin_title'] ?: $element['#title'] ?: $element['#webform_key'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getKey(array $element) {
+    return $element['#webform_key'];
+  }
+
+  /****************************************************************************/
+  // Display submission value methods.
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildHtml(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    return $this->build('html', $element, $webform_submission, $options);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildText(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    return $this->build('text', $element, $webform_submission, $options);
+  }
+
+  /**
+   * Build an element as text or HTML.
+   *
+   * @param string $format
+   *   Format of the element, text or html.
+   * @param array $element
+   *   An element.
+   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
+   *   A webform submission.
+   * @param array $options
+   *   An array of options.
+   *
+   * @return array
+   *   A render array representing an element as text or HTML.
+   */
+  protected function build($format, array &$element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    $options['multiline'] = $this->isMultiline($element);
+    $format_function = 'format' . ucfirst($format);
+    $value = $this->$format_function($element, $webform_submission, $options);
+
+    // Handle empty value.
+    if ($value === '') {
+      // Return NULL if empty is excluded.
+      if ($this->isEmptyExcluded($element, $options)) {
+        return NULL;
+      }
+      // Else set the formatted value to empty message/placeholder.
+      else {
+        $value = $this->configFactory->get('webform.settings')->get('element.empty_message');
+      }
+    }
+
+    // Convert string to renderable #markup.
+    if (is_string($value)) {
+      $value = ['#' . ($format === 'text' ? 'plain_text' : 'markup') => $value];
+    }
+
+    return [
+      '#theme' => 'webform_element_base_' . $format,
+      '#element' => $element,
+      '#value' => $value,
+      '#webform_submission' => $webform_submission,
+      '#options' => $options,
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formatHtml(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    return $this->format('Html', $element, $webform_submission, $options);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formatText(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    return $this->format('Text', $element, $webform_submission, $options);
+  }
+
+  /**
+   * Format an element's value as HTML or plain text.
+   *
+   * @param string $type
+   *   The format type, HTML or Text.
+   * @param array $element
+   *   An element.
+   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
+   *   A webform submission.
+   * @param array $options
+   *   An array of options.
+   *
+   * @return array|string
+   *   The element's value formatted as plain text or a render array.
+   */
+  protected function format($type, array &$element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    if (!$this->hasValue($element, $webform_submission, $options) && !$this->isContainer($element)) {
+      return '';
+    }
+
+    $item_function = 'format' . $type . 'Item';
+    $items_function = 'format' . $type . 'Items';
+    if ($this->hasMultipleValues($element)) {
+      // Return $options['delta'] which is used by tokens.
+      // @see _webform_token_get_submission_value()
+      if (isset($options['delta'])) {
+        return $this->$item_function($element, $webform_submission, $options);
+      }
+      elseif ($this->getItemsFormat($element) === 'custom' && !empty($element['#format_items_' . strtolower($type)])) {
+        return $this->formatCustomItems($type, $element, $webform_submission, $options);
+      }
+      else {
+        return $this->$items_function($element, $webform_submission, $options);
+      }
+    }
+    else {
+      if ($this->getItemFormat($element) === 'custom' && !empty($element['#format_' . strtolower($type)])) {
+        return $this->formatCustomItem($type, $element, $webform_submission, $options);
+      }
+      else {
+        return $this->$item_function($element, $webform_submission, $options);
+      }
+    }
+  }
+
+  /**
+   * Format an element's items using custom HTML or plain text.
+   *
+   * @param string $type
+   *   The format type, HTML or Text.
+   * @param array $element
+   *   An element.
+   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
+   *   A webform submission.
+   * @param array $options
+   *   An array of options.
+   * @param array $context
+   *   (optional) Context to be passed to inline Twig template.
+   *
+   * @return array|string
+   *   The element's items formatted as plain text or a render array.
+   */
+  protected function formatCustomItems($type, array &$element, WebformSubmissionInterface $webform_submission, array $options = [], array $context = []) {
+    $name = strtolower($type);
+
+    // Get value.
+    $value = $this->getValue($element, $webform_submission, $options);
+
+    // Get items.
+    $items = [];
+    $item_function = 'format' . $type . 'Item';
+    foreach (array_keys($value) as $delta) {
+      $items[] = $this->$item_function($element, $webform_submission, ['delta' => $delta] + $options);
+    }
+
+    // Get template.
+    $template = trim($element['#format_items_' . $name]);
+
+    // Get context.
+    $options += ['context' => []];
+    $context += [
+      'value' => $value,
+      'items' => $items,
+    ];
+
+    return WebformTwigExtension::buildTwigTemplate($webform_submission, $template, $options, $context);
+  }
+
+  /**
+   * Format an element's items as HTML.
+   *
+   * @param array $element
+   *   An element.
+   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
+   *   A webform submission.
+   * @param array $options
+   *   An array of options.
+   *
+   * @return string|array
+   *   The element's items as HTML.
+   */
+  protected function formatHtmlItems(array &$element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    $value = $this->getValue($element, $webform_submission, $options);
+
+    // Get items.
+    $items = [];
+    foreach (array_keys($value) as $delta) {
+      $items[] = $this->formatHtmlItem($element, $webform_submission, ['delta' => $delta] + $options);
+    }
+
+    $format = $this->getItemsFormat($element);
+    switch ($format) {
+      case 'ol':
+      case 'ul':
+        return [
+          '#theme' => 'item_list',
+          '#items' => $items,
+          '#list_type' => $format,
+        ];
+
+      case 'and':
+        $total = count($items);
+        if ($total === 1) {
+          $item = current($items);
+          return is_array($item) ? $item : ['#markup' => $item];
+        }
+
+        $build = [];
+        foreach ($items as $index => &$item) {
+          $build[] = (is_array($item)) ? $item : ['#markup' => $item];
+          if ($total === 2 && $index === 0) {
+            $build[] = ['#markup' => ' ' . t('and') . ' '];
+          }
+          elseif ($index !== ($total - 1)) {
+            if ($index === ($total - 2)) {
+              $build[] = ['#markup' => ', ' . t('and') . ' '];
+            }
+            else {
+              $build[] = ['#markup' => ', '];
+            }
+          }
+        }
+        return $build;
+
+      default:
+      case 'br':
+      case 'semicolon':
+      case 'comma':
+      case 'space':
+      case 'hr':
+        $delimiters = [
+          'hr' => '<hr class="webform-horizontal-rule" />',
+          'br' => '<br />',
+          'semicolon' => '; ',
+          'comma' => ', ',
+          'space' => ' ',
+        ];
+        $delimiter = (isset($delimiters[$format])) ? $delimiters[$format] : $format;
+
+        $total = count($items);
+
+        $build = [];
+        foreach ($items as $index => &$item) {
+          $build[] = (is_array($item)) ? $item : ['#markup' => $item];
+          if ($index !== ($total - 1)) {
+            $build[] = ['#markup' => $delimiter];
+          }
+        }
+        return $build;
+    }
+  }
+
+  /**
+   * Format an element's items as text.
+   *
+   * @param array $element
+   *   An element.
+   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
+   *   A webform submission.
+   * @param array $options
+   *   An array of options.
+   *
+   * @return string
+   *   The element's items as text.
+   */
+  protected function formatTextItems(array &$element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    $value = $this->getValue($element, $webform_submission, $options);
+
+    // Get items.
+    $items = [];
+    foreach (array_keys($value) as $delta) {
+      $items[] = $this->formatTextItem($element, $webform_submission, ['delta' => $delta] + $options);
+    }
+
+    $format = $this->getItemsFormat($element);
+    switch ($format) {
+      case 'ol':
+        $list = [];
+        $index = 1;
+        foreach ($items as $item) {
+          $prefix = ($index++) . '. ';
+          $list[] = $prefix . str_replace(PHP_EOL, PHP_EOL . str_repeat(' ', strlen($prefix)), $item);
+        }
+        return implode(PHP_EOL, $list);
+
+      case 'ul':
+        $list = [];
+        foreach ($items as $index => $item) {
+          $list[] = '- ' . str_replace(PHP_EOL, PHP_EOL . '  ', $item);
+        }
+        return implode(PHP_EOL, $list);
+
+      case 'and':
+        return WebformArrayHelper::toString($items);
+
+      default:
+      case 'br':
+      case 'semicolon':
+      case 'comma':
+      case 'space':
+      case 'hr':
+        $delimiters = [
+          'hr' => PHP_EOL . '---' . PHP_EOL,
+          'br' => PHP_EOL,
+          'semicolon' => '; ',
+          'comma' => ', ',
+          'space' => ' ',
+        ];
+        $delimiter = (isset($delimiters[$format])) ? $delimiters[$format] : $format;
+        return implode($delimiter, $items);
+    }
+  }
+
+  /**
+   * Format an element's item using custom HTML or plain text.
+   *
+   * @param string $type
+   *   The format type, HTML or Text.
+   * @param array $element
+   *   An element.
+   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
+   *   A webform submission.
+   * @param array $options
+   *   An array of options.
+   * @param array $context
+   *   (optional) Context to be passed to inline Twig template.
+   *
+   * @return array|string
+   *   The element's item formatted as plain text or a render array.
+   */
+  protected function formatCustomItem($type, array &$element, WebformSubmissionInterface $webform_submission, array $options = [], array $context = []) {
+    $name = strtolower($type);
+
+    // Get template.
+    $template = trim($element['#format_' . $name]);
+
+    // Get context.value.
+    $context['value'] = $this->getValue($element, $webform_submission, $options);
+
+    // Get content.item.
+    $context['item'] = [];
+    // Parse item.format from template and add to context.
+    if (preg_match_all("/item(?:\[['\"]|\.)([a-zA-Z0-9-_:]+)/", $template, $matches)) {
+      $formats = array_unique($matches[1]);
+      $item_function = 'format' . $type . 'Item';
+      foreach ($formats as $format) {
+        $context['item'][$format] = $this->$item_function(['#format' => $format] + $element, $webform_submission, $options);
+      }
+    }
+
+    // Return inline template.
+    if ($type === 'Text') {
+      return WebformTwigExtension::renderTwigTemplate($webform_submission, $template, $options, $context);
+    }
+    else {
+      return WebformTwigExtension::buildTwigTemplate($webform_submission, $template, $options, $context);
+    }
+  }
+
+  /**
+   * Format an element's value as HTML.
+   *
+   * @param array $element
+   *   An element.
+   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
+   *   A webform submission.
+   * @param array $options
+   *   An array of options.
+   *
+   * @return array|string
+   *   The element's value formatted as HTML or a render array.
+   */
+  protected function formatHtmlItem(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    $format = $this->getItemFormat($element);
+    $value = $this->formatTextItem($element, $webform_submission, ['prefixing' => FALSE] + $options);
+
+    if ($format === 'raw') {
+      return Markup::create($value);
+    }
+
+    // Build a render that used #plain_text so that HTML characters are escaped.
+    // @see \Drupal\Core\Render\Renderer::ensureMarkupIsSafe
+    $build = ['#plain_text' => $value];
+
+    $options += ['prefixing' => TRUE];
+    if ($options['prefixing']) {
+      if (isset($element['#field_prefix'])) {
+        $build['#prefix'] = $element['#field_prefix'];
+      }
+      if (isset($element['#field_suffix'])) {
+        $build['#suffix'] = $element['#field_suffix'];
+      }
+    }
+
+    return $build;
+  }
+
+  /**
+   * Format an element's value as text.
+   *
+   * @param array $element
+   *   An element.
+   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
+   *   A webform submission.
+   * @param array $options
+   *   An array of options.
+   *
+   * @return string
+   *   The element's value formatted as text.
+   *
+   * @see _webform_token_get_submission_value()
+   */
+  protected function formatTextItem(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    $value = $this->getValue($element, $webform_submission, $options);
+    $format = $this->getItemFormat($element);
+
+    if ($format === 'raw') {
+      return $value;
+    }
+
+    $options += ['prefixing' => TRUE];
+    if ($options['prefixing']) {
+      if (isset($element['#field_prefix'])) {
+        $value = strip_tags($element['#field_prefix']) . $value;
+      }
+      if (isset($element['#field_suffix'])) {
+        $value .= strip_tags($element['#field_suffix']);
+      }
+    }
+
+    return $value;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasValue(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    $value = $this->getValue($element, $webform_submission, $options);
+    return ($value === '' || $value === NULL || (is_array($value) && empty($value))) ? FALSE : TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getValue(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    if (!isset($element['#webform_key']) && isset($element['#value'])) {
+      return $element['#value'];
+    }
+
+    $webform_key = (isset($options['webform_key'])) ? $options['webform_key'] : $element['#webform_key'];
+    $value = $webform_submission->getElementData($webform_key);
+    // Is value is NULL and there is a #default_value, then use it.
+    if ($value === NULL && isset($element['#default_value'])) {
+      $value = $element['#default_value'];
+    }
+
+    // Return multiple (delta) value or composite (composite_key) value.
+    if (is_array($value)) {
+      // Return $options['delta'] which is used by tokens.
+      // @see _webform_token_get_submission_value()
+      if (isset($options['delta'])) {
+        $value = (isset($value[$options['delta']])) ? $value[$options['delta']] : NULL;
+      }
+
+      // Return $options['composite_key'] which is used by composite elements.
+      // @see \Drupal\webform\Plugin\WebformElement\WebformCompositeBase::formatTableColumn
+      if ($value && isset($options['composite_key'])) {
+        $value = (isset($value[$options['composite_key']])) ? $value[$options['composite_key']] : NULL;
+      }
+    }
+
+    return $value;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRawValue(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    $element['#format'] = 'raw';
+    return $this->getValue($element, $webform_submission, $options);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getItemFormats() {
+    return [
+      'value' => $this->t('Value'),
+      'raw' => $this->t('Raw value'),
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getItemDefaultFormat() {
+    return 'value';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getItemFormat(array $element) {
+    if (isset($element['#format'])) {
+      return $element['#format'];
+    }
+    elseif ($default_format = $this->configFactory->get('webform.settings')->get('format.' . $this->getPluginId() . '.item')) {
+      return $default_format;
+    }
+    else {
+      return $this->getItemDefaultFormat();
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getItemsDefaultFormat() {
+    return 'ul';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getItemsFormats() {
+    return [
+      'comma' => $this->t('Comma'),
+      'semicolon' => $this->t('Semicolon'),
+      'and' => $this->t('And'),
+      'ol' => $this->t('Ordered list'),
+      'ul' => $this->t('Unordered list'),
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getItemsFormat(array $element) {
+    if (isset($element['#format_items'])) {
+      return $element['#format_items'];
+    }
+    elseif ($default_format = $this->configFactory->get('webform.settings')->get('format.' . $this->getPluginId() . '.items')) {
+      return $default_format;
+    }
+    else {
+      return $this->getItemsDefaultFormat();
+    }
+  }
+
+  /****************************************************************************/
+  // Preview method.
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function preview() {
+    return [
+      '#type' => $this->getTypeName(),
+      '#title' => $this->getPluginLabel(),
+    ];
+  }
+
+  /****************************************************************************/
+  // Test methods.
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTestValues(array $element, WebformInterface $webform, array $options = []) {
+    return FALSE;
+  }
+
+  /****************************************************************************/
+  // Table methods.
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getTableColumn(array $element) {
+    $key = $element['#webform_key'];
+    return [
+      'element__' . $key => [
+        'title' => $this->getAdminLabel($element),
+        'sort' => TRUE,
+        'key' => $key,
+        'property_name' => NULL,
+        'element' => $element,
+        'plugin' => $this,
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formatTableColumn(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    return $this->formatHtml($element, $webform_submission);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isEmptyExcluded(array $element, array $options) {
+    $options += [
+      'exclude_empty' => TRUE,
+    ];
+    return !empty($options['exclude_empty']);
+  }
+
+  /****************************************************************************/
+  // Export methods.
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getExportDefaultOptions() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildExportOptionsForm(array &$form, FormStateInterface $form_state, array $export_options) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildExportHeader(array $element, array $export_options) {
+    if ($export_options['header_format'] == 'label') {
+      return [$this->getAdminLabel($element)];
+    }
+    else {
+      return [$element['#webform_key']];
+    }
+  }
+
+  /**
+   * Prefix an element's export header.
+   *
+   * @param array $header
+   *   An element's export header.
+   * @param array $element
+   *   An element.
+   * @param array $export_options
+   *   An associative array of export options.
+   *
+   * @return array
+   *   An element's export header with prefix.
+   */
+  protected function prefixExportHeader(array $header, array $element, array $export_options) {
+    if (empty($export_options['header_prefix'])) {
+      return $header;
+    }
+
+    if ($export_options['header_format'] == 'label') {
+      $prefix = $this->getAdminLabel($element) . $export_options['header_prefix_label_delimiter'];
+    }
+    else {
+      $prefix = $this->getKey($element) . $export_options['header_prefix_key_delimiter'];
+    }
+
+    foreach ($header as $index => $column) {
+      $header[$index] = $prefix . $column;
+    }
+
+    return $header;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildExportRecord(array $element, WebformSubmissionInterface $webform_submission, array $export_options) {
+    $element['#format_items'] = $export_options['multiple_delimiter'];
+    return [$this->formatText($element, $webform_submission, $export_options)];
+  }
+
+  /****************************************************************************/
+  // Validation methods.
+  /****************************************************************************/
+
+  /**
+   * Form API callback. Validate element #minlength value.
+   */
+  public static function validateMinlength(&$element, FormStateInterface &$form_state) {
+    if (!isset($element['#minlength'])) {
+      return;
+    }
+
+    if (!empty($element['#value']) && mb_strlen($element['#value']) < $element['#minlength']) {
+      $t_args = [
+        '%name' => empty($element['#title']) ? $element['#parents'][0] : $element['#title'],
+        '%min' => $element['#minlength'],
+        '%length' => mb_strlen($element['#value']),
+      ];
+      $form_state->setError($element, t('%name cannot be less than %min characters but is currently %length characters long.', $t_args));
+    }
+  }
+
+  /**
+   * Form API callback. Validate element #unique value.
+   */
+  public static function validateUnique(array &$element, FormStateInterface $form_state) {
+    if (!isset($element['#unique'])) {
+      return;
+    }
+
+    /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
+    $element_manager = \Drupal::service('plugin.manager.webform.element');
+
+    $name = $element['#webform_key'];
+    $value = NestedArray::getValue($form_state->getValues(), $element['#parents']);
+
+    // Skip composite elements.
+    $element_plugin = $element_manager->getElementInstance($element);
+    if ($element_plugin->isComposite()) {
+      return;
+    }
+
+    // Skip empty values but allow for '0'.
+    if ($value === '' || $value === NULL || (is_array($value) && empty($value))) {
+      return;
+    }
+
+    /** @var \Drupal\webform\WebformSubmissionForm $form_object */
+    $form_object = $form_state->getFormObject();
+    /** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
+    $webform_submission = $form_object->getEntity();
+    $webform = $webform_submission->getWebform();
+
+    // Build unique query which return a single duplicate value.
+    $query = \Drupal::database()->select('webform_submission', 'ws');
+    $query->leftJoin('webform_submission_data', 'wsd', 'ws.sid = wsd.sid');
+    $query->fields('wsd', ['value']);
+    $query->condition('wsd.webform_id', $webform->id());
+    $query->condition('wsd.name', $name);
+    $query->condition('wsd.value', (array) $value, 'IN');
+    // Unique user condition.
+    if (!empty($element['#unique_user'])) {
+      $query->condition('ws.uid', $webform_submission->getOwnerId());
+    }
+    // Unique (source) entity condition.
+    if (!empty($element['#unique_entity'])) {
+      if ($source_entity = $webform_submission->getSourceEntity()) {
+        $query->condition('ws.entity_type', $source_entity->getEntityTypeId());
+        $query->condition('ws.entity_id', $source_entity->id());
+      }
+      else {
+        $query->isNull('ws.entity_type');
+        $query->isNull('ws.entity_id');
+      }
+    }
+    // Exclude the current webform submission.
+    if ($sid = $webform_submission->id()) {
+      $query->condition('ws.sid', $sid, '<>');
+    }
+    // Get single duplicate value.
+    $query->range(0, 1);
+    $duplicate_value = $query->execute()->fetchField();
+
+    // Skip NULL or empty string value.
+    if ($duplicate_value === FALSE || $duplicate_value === '') {
+      return;
+    }
+
+    if (isset($element['#unique_error'])) {
+      $form_state->setError($element, WebformHtmlHelper::toHtmlMarkup($element['#unique_error']));
+    }
+    elseif (isset($element['#title'])) {
+      // Get #options display value.
+      if (isset($element['#options'])) {
+        $duplicate_value = WebformOptionsHelper::getOptionText($duplicate_value, $element['#options'], TRUE);
+      }
+      $t_args = [
+        '%name' => empty($element['#title']) ? $element['#parents'][0] : $element['#title'],
+        '%value' => $duplicate_value,
+      ];
+      $form_state->setError($element, t('The value %value has already been submitted once for the %name element. You may have already submitted this webform, or you need to use a different value.', $t_args));
+    }
+    else {
+      $form_state->setError($element);
+    }
+  }
+
+  /**
+   * Form API callback. Validate element #unique multiple values.
+   */
+  public static function validateUniqueMultiple(array &$element, FormStateInterface $form_state) {
+    if (!isset($element['#unique'])) {
+      return;
+    }
+
+    $name = $element['#name'];
+    $value = NestedArray::getValue($form_state->getValues(), $element['#parents']);
+
+    if (empty($value)) {
+      return;
+    }
+
+    // Compare number of values to unique number of values.
+    if (count($value) != count(array_unique($value))) {
+      $duplicates = WebformArrayHelper::getDuplicates($value);
+
+      if (isset($element['#unique_error'])) {
+        $form_state->setError($element, WebformHtmlHelper::toHtmlMarkup($element['#unique_error']));
+      }
+      elseif (isset($element['#title'])) {
+        $t_args = [
+          '%name' => empty($element['#title']) ? $name : $element['#title'],
+          '%value' => reset($duplicates),
+        ];
+        $form_state->setError($element, t('The value %value has already been submitted once for the %name element. You may have already submitted this webform, or you need to use a different value.', $t_args));
+      }
+      else {
+        $form_state->setError($element);
+      }
+    }
+  }
+
+  /**
+   * Form API callback. Validate element #multiple > 1 value.
+   */
+  public static function validateMultiple(array &$element, FormStateInterface $form_state) {
+    if (!isset($element['#multiple'])) {
+      return;
+    }
+
+    // IMPORTANT: Must get values from the $form_states since sub-elements
+    // may call $form_state->setValueForElement() via their validation hook.
+    // @see \Drupal\webform\Element\WebformEmailConfirm::validateWebformEmailConfirm
+    // @see \Drupal\webform\Element\WebformOtherBase::validateWebformOther
+    $values = NestedArray::getValue($form_state->getValues(), $element['#parents']);
+
+    // Skip empty values or values that are not an array.
+    if (empty($values) || !is_array($values)) {
+      return;
+    }
+
+    if (count($values) > $element['#multiple']) {
+      if (isset($element['#multiple_error'])) {
+        $form_state->setError($element, $element['#multiple_error']);
+      }
+      elseif (isset($element['#title'])) {
+        $t_args = [
+          '%name' => empty($element['#title']) ? $element['#parents'][0] : $element['#title'],
+          '@count' => $element['#multiple'],
+        ];
+        $form_state->setError($element, t('%name: this element cannot hold more than @count values.', $t_args));
+      }
+      else {
+        $form_state->setError($element);
+      }
+    }
+  }
+
+  /****************************************************************************/
+  // #states API methods.
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementStateOptions() {
+    $visibility_optgroup = (string) $this->t('Visibility');
+    $state_optgroup = (string) $this->t('State');
+    $validation_optgroup = (string) $this->t('Validation');
+    $value_optgroup = (string) $this->t('Value');
+
+    $states = [];
+
+    // Set default states that apply to the element/container and sub elements.
+    $states += [
+      $visibility_optgroup => [
+        'visible' => $this->t('Visible'),
+        'invisible' => $this->t('Hidden'),
+        'visible-slide' => $this->t('Visible (Slide)'),
+        'invisible-slide' => $this->t('Hidden (Slide)'),
+      ],
+      $state_optgroup => [
+        'enabled' => $this->t('Enabled'),
+        'disabled' => $this->t('Disabled'),
+      ],
+      $validation_optgroup => [
+        'required' => $this->t('Required'),
+        'optional' => $this->t('Optional'),
+      ],
+    ];
+
+    // Set readwrite/readonly states for any element that supports it
+    // and containers.
+    if ($this->hasProperty('readonly') || $this->isContainer(['#type' => $this->getPluginId()])) {
+      $states[$state_optgroup] += [
+        'readwrite' => $this->t('Read/write'),
+        'readonly' => $this->t('Read-only'),
+      ];
+    }
+
+    // Set checked/unchecked states for any element that contains checkboxes.
+    if ($this instanceof Checkbox || $this instanceof Checkboxes) {
+      $states[$value_optgroup] = [
+        'checked' => $this->t('Checked'),
+        'unchecked' => $this->t('Unchecked'),
+      ];
+    }
+
+    // Set expanded/collapsed states for any details element.
+    if ($this instanceof Details) {
+      $states[$state_optgroup] += [
+        'expanded' => $this->t('Expanded'),
+        'collapsed' => $this->t('Collapsed'),
+      ];
+    }
+
+    return $states;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementSelectorOptions(array $element) {
+    if ($this->hasMultipleValues($element) && $this->hasMultipleWrapper()) {
+      return [];
+    }
+
+    $title = $this->getAdminLabel($element) . ' [' . $this->getPluginLabel() . ']';
+    $name = $element['#webform_key'];
+
+    if ($inputs = $this->getElementSelectorInputsOptions($element)) {
+      $selectors = [];
+      foreach ($inputs as $input_name => $input_title) {
+        $selectors[":input[name=\"{$name}[{$input_name}]\"]"] = $input_title;
+      }
+      return [$title => $selectors];
+    }
+    else {
+      return [":input[name=\"$name\"]" => $title];
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementSelectorSourceValues(array $element) {
+    return [];
+  }
+
+  /**
+   * Get an element's (sub)inputs selectors as options.
+   *
+   * @param array $element
+   *   An element.
+   *
+   * @return array
+   *   An array of element (sub)input selectors.
+   */
+  protected function getElementSelectorInputsOptions(array $element) {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getElementSelectorInputValue($selector, $trigger, array $element, WebformSubmissionInterface $webform_submission) {
+    if ($this->isComposite()) {
+      $input_name = WebformSubmissionConditionsValidator::getSelectorInputName($selector);
+      $composite_key = WebformSubmissionConditionsValidator::getInputNameAsArray($input_name, 1);
+      if ($composite_key) {
+        return $this->getRawValue($element, $webform_submission, ['composite_key' => $composite_key]);
+      }
+      else {
+        return NULL;
+      }
+    }
+    else {
+      return $this->getRawValue($element, $webform_submission);
+    }
+  }
+
+  /****************************************************************************/
+  // Operation methods.
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function preCreate(array &$element, array &$values) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function postCreate(array &$element, WebformSubmissionInterface $webform_submission) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function postLoad(array &$element, WebformSubmissionInterface $webform_submission) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function preDelete(array &$element, WebformSubmissionInterface $webform_submission) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function postDelete(array &$element, WebformSubmissionInterface $webform_submission) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function preSave(array &$element, WebformSubmissionInterface $webform_submission) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function postSave(array &$element, WebformSubmissionInterface $webform_submission, $update = TRUE) {}
+
+  /****************************************************************************/
+  // Element configuration methods.
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function form(array $form, FormStateInterface $form_state) {
+    /** @var \Drupal\webform_ui\Form\WebformUiElementFormInterface $form_object */
+    $form_object = $form_state->getFormObject();
+    $webform = $form_object->getWebform();
+
+    $element_properties = $form_state->get('element_properties');
+
+    /**************************************************************************/
+    // General.
+    /**************************************************************************/
+
+    /* Element settings */
+
+    $form['element'] = [
+      '#type' => 'fieldset',
+      '#title' => $this->t('Element settings'),
+      '#access' => TRUE,
+      '#weight' => -50,
+    ];
+    $form['element']['title'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Title'),
+      '#maxlength' => NULL,
+      '#description' => $this->t('This is used as a descriptive label when displaying this webform element.'),
+      '#required' => TRUE,
+      '#attributes' => ['autofocus' => 'autofocus'],
+    ];
+    $form['element']['value'] = [
+      '#type' => 'textarea',
+      '#title' => $this->t('Value'),
+      '#description' => $this->t('The value of the webform element.'),
+    ];
+    $form['element']['multiple'] = [
+      '#title' => $this->t('Allowed number of values'),
+      '#type' => 'webform_element_multiple',
+    ];
+    $form['element']['multiple_error'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Custom allowed number of values error message'),
+      '#description' => $this->t('If set, this message will be used when an element\'s allowed number of values is exceeded, instead of the default "@message" message.', ['@message' => $this->t('%name: this element cannot hold more than @count values.')]),
+      '#states' => [
+        'visible' => [
+          ':input[name="properties[multiple][container][cardinality]"]' => ['value' => 'number'],
+          ':input[name="properties[multiple][container][cardinality_number]"]' => ['!value' => 1],
+        ],
+      ],
+    ];
+
+    /* Element description/help/more */
+
+    $form['element_description'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Element description/help/more'),
+    ];
+    $form['element_description']['description'] = [
+      '#type' => 'webform_html_editor',
+      '#title' => $this->t('Description'),
+      '#description' => $this->t('A short description of the element used as help for the user when he/she uses the webform.'),
+    ];
+    $form['element_description']['help'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Help'),
+      '#description' => $this->t("Displays a help tooltip after the element's title."),
+      '#states' => [
+        'invisible' => [
+          [':input[name="properties[title_display]"]' => ['value' => 'invisible']],
+        ],
+      ],
+    ];
+    $form['element_description']['help']['help_title'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Help title'),
+      '#description' => $this->t("The text displayed in help tooltip after the element's title.") . '<br /><br />' .
+        $this->t("Defaults to the element's title"),
+    ];
+    $form['element_description']['help']['help'] = [
+      '#type' => 'webform_html_editor',
+      '#title' => $this->t('Help text'),
+      '#description' => $this->t("The text displayed in help tooltip after the element's title."),
+    ];
+    $form['element_description']['more'] = [
+      '#type' => 'details',
+      '#title' => $this->t('More'),
+      '#description' => $this->t("Displays a read more hide/show widget below the element's description."),
+    ];
+    $form['element_description']['more']['more_title'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('More title'),
+      '#description' => $this->t('The click-able label used to open and close more text.') . '<br /><br />' .
+        $this->t('Defaults to: %value', ['%value' => $this->configFactory->get('webform.settings')->get('element.default_more_title')]),
+    ];
+    $form['element_description']['more']['more'] = [
+      '#type' => 'webform_html_editor',
+      '#title' => $this->t('More text'),
+      '#description' => $this->t('A long description of the element that provides form additional information which can opened and closed.'),
+    ];
+
+    /* Form display */
+    $form['form'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Form display'),
+    ];
+    $form['form']['display_container'] = $this->getFormInlineContainer();
+    $form['form']['display_container']['title_display'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Title display'),
+      '#empty_option' => $this->t('- Default -'),
+      '#options' => [
+        'before' => $this->t('Before'),
+        'after' => $this->t('After'),
+        'inline' => $this->t('Inline'),
+        'invisible' => $this->t('Invisible'),
+        'none' => $this->t('None'),
+      ],
+      '#description' => $this->t('Determines the placement of the title.'),
+    ];
+    // Displaying the title after the element is not supported by
+    // the composite (fieldset) wrapper.
+    if ($this->hasCompositeFormElementWrapper()) {
+      unset($form['form']['display_container']['title_display']['#options']['after']);
+    }
+    $form['form']['display_container']['description_display'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Description display'),
+      '#empty_option' => $this->t('- Default -'),
+      '#options' => [
+        'before' => $this->t('Before'),
+        'after' => $this->t('After'),
+        'invisible' => $this->t('Invisible'),
+        'tooltip' => $this->t('Tooltip'),
+      ],
+      '#description' => $this->t('Determines the placement of the description.'),
+    ];
+    $form['form']['display_container']['help_display'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Help display'),
+      '#empty_option' => $this->t('- Default -'),
+      '#options' => [
+        'title_before' => $this->t('Before title'),
+        'title_after' => $this->t('After title'),
+        'element_before' => $this->t('Before element'),
+        'element_after' => $this->t('After element'),
+      ],
+      '#description' => $this->t('Determines the placement of the help tooltip.'),
+    ];
+    if ($this->hasProperty('title_display')) {
+      $form['form']['title_display_message'] = [
+        '#type' => 'webform_message',
+        '#message_type' => 'warning',
+        '#message_message' => $this->t("Please note: Settings the element's title display to 'none' means the title will not be rendered or accessible to screenreaders"),
+        '#message_close' => TRUE,
+        '#message_storage' => WebformMessage::STORAGE_LOCAL,
+        '#access' => TRUE,
+        '#states' => [
+          'visible' => [
+            ':input[name="properties[title_display]"]' => ['value' => 'none'],
+          ],
+        ],
+      ];
+    }
+
+    // Remove unsupported title and description display from composite elements.
+    if ($this->isComposite()) {
+      unset($form['form']['display_container']['title_display']['#options']['inline']);
+      unset($form['form']['display_container']['description_display']['#options']['tooltip']);
+    }
+    // Remove unsupported title display from certain element types.
+    $element_types = [
+      'webform_codemirror',
+      'webform_email_confirm',
+      'webform_htmleditor',
+      'webform_mapping',
+      'webform_signature',
+    ];
+    if (in_array($this->getPluginId(), $element_types)) {
+      unset($form['form']['display_container']['title_display']['#options']['inline']);
+    }
+    // Remove unsupported title display from certain element types.
+    $element_types = [
+      'fieldset',
+      'details',
+      'webform_codemirror',
+      'webform_email_confirm',
+      'webform_htmleditor',
+      'webform_image_select',
+      'webform_likert',
+      'webform_mapping',
+      'webform_signature',
+    ];
+    if (in_array($this->getPluginId(), $element_types)) {
+      unset($form['form']['display_container']['title_display']['#options']['inline']);
+    }
+
+    $form['form']['field_container'] = $this->getFormInlineContainer();
+    $form['form']['field_container']['field_prefix'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Field prefix'),
+      '#description' => $this->t('Text or code that is placed directly in front of the input. This can be used to prefix an input with a constant string. Examples: $, #, -.'),
+      '#size' => 10,
+    ];
+    $form['form']['field_container']['field_suffix'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Field suffix'),
+      '#description' => $this->t('Text or code that is placed directly after the input. This can be used to add a unit to an input. Examples: lb, kg, %.'),
+      '#size' => 10,
+    ];
+    $form['form']['length_container'] = $this->getFormInlineContainer();
+    $form['form']['length_container']['minlength'] = [
+      '#type' => 'number',
+      '#title' => $this->t('Minlength'),
+      '#description' => $this->t('The element may still be empty unless it is required.'),
+      '#min' => 1,
+      '#size' => 4,
+    ];    $form['form']['length_container']['maxlength'] = [
+      '#type' => 'number',
+      '#title' => $this->t('Maxlength'),
+      '#description' => $this->t('Leaving blank will use the default maxlength.'),
+      '#min' => 1,
+      '#size' => 4,
+    ];
+    $form['form']['size_container'] = $this->getFormInlineContainer();
+    $form['form']['size_container']['size'] = [
+      '#type' => 'number',
+      '#title' => $this->t('Size'),
+      '#description' => $this->t('Leaving blank will use the default size.'),
+      '#min' => 1,
+      '#size' => 4,
+    ];
+    $form['form']['size_container']['rows'] = [
+      '#type' => 'number',
+      '#title' => $this->t('Rows'),
+      '#description' => $this->t('Leaving blank will use the default rows.'),
+      '#min' => 1,
+      '#size' => 4,
+    ];
+    $form['form']['placeholder'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Placeholder'),
+      '#description' => $this->t('The placeholder will be shown in the element until the user starts entering a value.'),
+    ];
+    $form['form']['autocomplete'] = [
+      '#type' => 'webform_select_other',
+      '#title' => $this->t('Autocomplete'),
+      '#description' => $this->t("Setting autocomplete to off will disable autocompletion for this element. Select 'Autofill' to use semantic attribute values for collecting certain types of user information."),
+      '#options' => [
+        'on' => $this->t('On'),
+        'off' => $this->t('Off'),
+      ],
+      '#other__type' => 'select',
+      '#other__option_label' => $this->t('Autofill…'),
+      '#other__title' => $this->t('Autocomplete autofill'),
+      '#other__description' => $this->t("Browsers sometimes have features for helping users fill forms in, for example prefilling the user's address based on earlier user input. The autocomplete (autofill) attribute can be used to hint to the user agent how to, or indeed whether to, provide such a feature."),
+      '#other__options' => [
+        (string) $this->t('Biographical attributes') => [
+          "name" => $this->t('Full name'),
+          "honorific-prefix" => $this->t('Honorific prefix'),
+          "given-name" => $this->t('Given name'),
+          "additional-name" => $this->t('Additional names'),
+          "family-name" => $this->t('Family name'),
+          "honorific-suffix" => $this->t('Honorific suffix'),
+          "nickname" => $this->t('Nickname'),
+          "username" => $this->t('Username'),
+          "new-password" => $this->t('New password'),
+          "current-password" => $this->t('Current password'),
+          "organization-title" => $this->t('Organization job title'),
+          "organization" => $this->t('Organization name'),
+          "language" => $this->t('Preferred language'),
+          "bday" => $this->t('Birthday'),
+          "bday-day" => $this->t('Birthday day'),
+          "bday-month" => $this->t('Birthday month'),
+          "bday-year" => $this->t('Birthday year'),
+          "sex" => $this->t('Gender'),
+          "url" => $this->t('Contact URL'),
+          "photo" => $this->t('Contact photo'),
+          "email" => $this->t('Email'),
+          "impp" => $this->t('Instant messaging URL'),
+        ],
+        (string) $this->t('Address attributes') => [
+          "street-address" => $this->t('Street address (multiline)'),
+          "address-line1" => $this->t('Address line 1'),
+          "address-line2" => $this->t('Address line 2'),
+          "address-line3" => $this->t('Address line 3'),
+          "address-level1" => $this->t('Address level 1'),
+          "address-level2" => $this->t('Address level 2'),
+          "address-level3" => $this->t('Address level 3'),
+          "address-level4" => $this->t('Address level 4'),
+          "country" => $this->t('Country code'),
+          "country-name" => $this->t('Country name'),
+          "postal-code" => $this->t('Postal code / Zip code'),
+        ],
+        (string) $this->t('Telephone attributes') => [
+          "tel" => $this->t('Telephone'),
+          "home tel" => $this->t('Telephone - home'),
+          "work tel" => $this->t('Telephone - work'),
+          "work tel-extension" => $this->t('Telephone - work extension'),
+          "mobile tel" => $this->t('Telephone - mobile'),
+          "fax tel" => $this->t('Telephone - fax'),
+          "pager tel" => $this->t('Telephone - pager'),
+          "tel-country-code" => $this->t('Telephone country code'),
+          "tel-national" => $this->t('Telephone national code'),
+          "tel-area-code" => $this->t('Telephone area code'),
+          "tel-local" => $this->t('Telephone local number'),
+          "tel-local-prefix" => $this->t('Telephone local prefix'),
+          "tel-local-suffix" => $this->t('Telephone local suffix'),
+          "tel-extension" => $this->t('Telephone extension'),
+        ],
+        (string) $this->t('Commerce attributes') => [
+          "cc-name" => $this->t('Name on card'),
+          "cc-given-name" => $this->t('Given name on card'),
+          "cc-additional-name" => $this->t('Additional names on card'),
+          "cc-family-name" => $this->t('Family name on card'),
+          "cc-number" => $this->t('Card number'),
+          "cc-exp" => $this->t('Card expiry date'),
+          "cc-exp-month" => $this->t('Card expiry month'),
+          "cc-exp-year" => $this->t('Card expiry year'),
+          "cc-csc" => $this->t('Card Security Code'),
+          "cc-type" => $this->t('Card type'),
+          "transaction-currency" => $this->t('Transaction currency'),
+          "transaction-amount" => $this->t('Transaction amount'),
+        ],
+      ],
+    ];
+    $form['form']['disabled'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Disabled'),
+      '#description' => $this->t('Make this element non-editable with the user entered (e.g. via developer tools) value <strong>ignored</strong>. Useful for displaying default value. Changeable via JavaScript.'),
+      '#return_value' => TRUE,
+      '#weight' => 50,
+    ];
+    $form['form']['readonly'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Readonly'),
+      '#description' => $this->t('Make this element non-editable with the user entered (e.g. via developer tools) value <strong>submitted</strong>. Useful for displaying default value. Changeable via JavaScript.'),
+      '#return_value' => TRUE,
+      '#weight' => 50,
+    ];
+    $form['form']['prepopulate'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Prepopulate'),
+      '#description' => $this->t('Allow element to be populated using query string parameters.'),
+      '#return_value' => TRUE,
+      '#weight' => 50,
+    ];
+    // Disabled check element when prepopulate is enabled for all elements.
+    if ($webform->getSetting('form_prepopulate') && $this->hasProperty('prepopulate')) {
+      $form['form']['prepopulate_disabled'] = [
+        '#description' => $this->t('Prepopulation is enabled for all form elements.'),
+        '#value' => TRUE,
+        '#disabled' => TRUE,
+        '#access' => TRUE,
+      ] + $form['form']['prepopulate'];
+      $form['form']['prepopulate']['#value'] = FALSE;
+      $form['form']['prepopulate']['#access'] = FALSE;
+    }
+    $form['form']['open'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Open'),
+      '#description' => $this->t('Contents should be visible (open) to the user.'),
+      '#return_value' => TRUE,
+      '#weight' => 50,
+    ];
+
+    /* Validation */
+
+    // Placeholder webform elements with #options.
+    // @see \Drupal\webform\Plugin\WebformElement\OptionsBase::form
+    $form['options'] = [];
+    $form['options_other'] = [];
+
+    $form['validation'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Form validation'),
+    ];
+    $error_messages = ['required_error', 'unique_error', 'pattern_error'];
+    $validation_html_message_states = [];
+    foreach ($error_messages as $error_message) {
+      if ($this->hasProperty($error_message)) {
+        if ($validation_html_message_states) {
+          $validation_html_message_states[] = 'or';
+        }
+        $validation_html_message_states[] = [':input[name="properties[' . $error_message . ']"]' => ['value' => ['pattern' => '(<[a-z][^>]*>|&(?:[a-z]+|#\d+);)']]];
+      }
+    }
+    if ($validation_html_message_states) {
+      $form['validation']['html_message'] = [
+        '#type' => 'webform_message',
+        '#message_message' => $this->t('Validation error message contains HTML markup. HTML markup can not be display via HTML5 clientside validation and will be removed.'),
+        '#message_type' => 'warning',
+        '#states' => ['visible' => $validation_html_message_states],
+        '#access' => TRUE,
+      ];
+    }
+    $form['validation']['required_container'] = [
+      '#type' => 'container',
+    ];
+    $form['validation']['required_container']['required'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Required'),
+      '#description' => $this->t('Check this option if the user must enter a value.'),
+      '#return_value' => TRUE,
+    ];
+    $form['validation']['required_container']['required_error'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Required message'),
+      '#description' => $this->t('If set, this message will be used when a required webform element is empty, instead of the default "Field x is required." message.'),
+      '#states' => [
+        'visible' => [
+          ':input[name="properties[required]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+    $form['validation']['unique_container'] = $this->getFormInlineContainer();
+    $form['validation']['unique_container']['unique'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Unique'),
+      '#description' => $this->t('Check that all entered values for this element are unique.'),
+      '#return_value' => TRUE,
+    ];
+    $form['validation']['unique_container']['unique_entity'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Unique per entity'),
+      '#description' => $this->t('Check that entered values for this element is unique for the current source entity.'),
+      '#return_value' => TRUE,
+      '#states' => [
+        'visible' => [
+          ['input[name="properties[unique]"]' => ['checked' => TRUE]],
+        ],
+      ],
+    ];
+    $form['validation']['unique_container']['unique_user'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Unique per user'),
+      '#description' => $this->t('Check that entered values for this element are unique for the current user.'),
+      '#return_value' => TRUE,
+      '#states' => [
+        'visible' => [
+          ['input[name="properties[unique]"]' => ['checked' => TRUE]],
+        ],
+      ],
+    ];
+    $form['validation']['unique_error'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Unique message'),
+      '#description' => $this->t('If set, this message will be used when an element\'s value are not unique, instead of the default "@message" message.', ['@message' => $this->t('The value %value has already been submitted once for the %name element. You may have already submitted this webform, or you need to use a different value.')]),
+      '#states' => [
+        'visible' => [
+          [':input[name="properties[unique]"]' => ['checked' => TRUE]],
+        ],
+      ],
+    ];
+
+    /* Flexbox item */
+
+    $form['flex'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Flexbox item'),
+      '#description' => $this->t('Learn more about using <a href=":href">flexbox layouts</a>.', [':href' => 'http://www.w3schools.com/css/css3_flexbox.asp']),
+    ];
+    $flex_range = range(0, 12);
+    $form['flex']['flex'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Flex'),
+      '#description' => $this->t('The flex property specifies the length of the item, relative to the rest of the flexible items inside the same container.') . '<br /><br />' .
+      $this->t('Defaults to: %value', ['%value' => 1]),
+      '#options' => [0 => $this->t('0 (none)')] + array_combine($flex_range, $flex_range),
+    ];
+
+    /**************************************************************************/
+    // Conditions.
+    /**************************************************************************/
+
+    /* Conditional logic */
+
+    $form['conditional_logic'] = [
+      '#type' => 'fieldset',
+      '#title' => $this->t('Conditional logic'),
+    ];
+    $form['conditional_logic']['states'] = [
+      '#type' => 'webform_element_states',
+      '#state_options' => $this->getElementStateOptions(),
+      '#selector_options' => $webform->getElementsSelectorOptions(),
+      '#selector_sources' => $webform->getElementsSelectorSourceValues(),
+      '#disabled_message' => TRUE,
+    ];
+    $form['conditional_logic']['states_clear'] = [
+      '#type' => 'checkbox',
+      '#title' => 'Clear value(s) when hidden',
+      '#return_value' => TRUE,
+      '#description' => ($this instanceof ContainerBase) ?
+        $this->t("When this container is hidden all this container's subelement values will be cleared.")
+        :
+        $this->t("When this element is hidden, this element's value will be cleared."),
+    ];
+    if ($this->hasProperty('states') && $this->hasProperty('required')) {
+      $form['conditional_logic']['states_required_message'] = [
+        '#type' => 'webform_message',
+        '#message_type' => 'warning',
+        '#message_message' => $this->t('Please note when an element is hidden it will not be required.'),
+        '#access' => TRUE,
+        '#states' => [
+          'visible' => [
+            ':input[name="properties[required]"]' => ['checked' => TRUE],
+          ],
+        ],
+      ];
+    }
+
+    /**************************************************************************/
+    // Advanced.
+    /**************************************************************************/
+
+    /* Default value */
+
+    $form['default'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Default value'),
+    ];
+    if ($this->isComposite()) {
+      $form['default']['default_value'] = [
+        '#type' => 'webform_codemirror',
+        '#mode' => 'yaml',
+        '#title' => $this->t('Default value'),
+      ];
+    }
+    else {
+      $form['default']['default_value'] = [
+        '#type' => 'textfield',
+        '#title' => $this->t('Default value'),
+        '#maxlength' => NULL,
+      ];
+    }
+    $form['default']['default_value']['#description'] = $this->t('The default value of the webform element.');
+    if ($this->hasProperty('multiple')) {
+      $form['default']['default_value']['#description'] .= ' ' . $this->t('For multiple options, use commas to separate multiple defaults.');
+    }
+
+    // Multiple.
+    $form['multiple'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Multiple settings'),
+      '#states' => [
+        'invisible' => [
+          ':input[name="properties[multiple][container][cardinality]"]' => ['!value' => -1],
+          ':input[name="properties[multiple][container][cardinality_number]"]' => ['value' => 1],
+        ],
+      ],
+      '#attributes' => ['data-webform-states-no-clear' => TRUE],
+    ];
+    $form['multiple']['multiple__header'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Display elements in table columns'),
+      '#description' => $this->t("If checked, the composite sub-element titles will be displayed as the table header labels."),
+      '#return_value' => TRUE,
+    ];
+    $form['multiple']['multiple__header_label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Table header label'),
+      '#description' => $this->t('This is used as the table header for this webform element when displaying multiple values.'),
+    ];
+    $form['multiple']['multiple__no_items_message'] = [
+      '#type' => 'webform_html_editor',
+      '#title' => $this->t('No items message'),
+      '#description' => $this->t('This is used when there are no items entered.'),
+    ];
+    $form['multiple']['multiple__min_items'] = [
+      '#type' => 'number',
+      '#title' => $this->t('Minimum amount of items'),
+      '#description' => $this->t('Minimum items defaults to 0 for optional elements and 1 for required elements.'),
+      '#min' => 0,
+      '#max' => 20,
+    ];
+    $form['multiple']['multiple__empty_items'] = [
+      '#type' => 'number',
+      '#title' => $this->t('Number of empty items'),
+      '#required' => TRUE,
+      '#min' => 0,
+      '#max' => 20,
+    ];
+    $form['multiple']['multiple__sorting'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Allow users to sort elements'),
+      '#description' => $this->t('If unchecked, the elements will no longer be sortable.'),
+      '#return_value' => TRUE,
+    ];
+    $form['multiple']['multiple__operations'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Allow users to add/remove elements'),
+      '#description' => $this->t('If unchecked, the add/remove (+/x) buttons will be removed from each table row.'),
+      '#return_value' => TRUE,
+    ];
+    $form['multiple']['multiple__add_more'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Allow users to add more items'),
+      '#description' => $this->t('If checked, an add more input will be added below the multiple values.'),
+      '#return_value' => TRUE,
+    ];
+    $form['multiple']['multiple__add_more_container'] = [
+      '#type' => 'container',
+      '#states' => [
+        'visible' => [
+          ':input[name="properties[multiple__add_more]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+    $form['multiple']['multiple__add_more_container']['multiple__add_more_input'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Allow users to input the number of items to be added'),
+      '#description' => $this->t('If checked, users will be able to input the number of items to be added.'),
+      '#return_value' => TRUE,
+    ];
+    $form['multiple']['multiple__add_more_container']['multiple__add_more_button_label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Add more button label'),
+      '#description' => $this->t('This is used as the add more items button label for this webform element when displaying multiple values.'),
+    ];
+    $form['multiple']['multiple__add_more_container']['multiple__add_more_input_label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Add more input label'),
+      '#description' => $this->t('This is used as the add more items input label for this webform element when displaying multiple values.'),
+      '#states' => [
+        'visible' => [
+          ':input[name="properties[multiple__add_more_input]"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+    $form['multiple']['multiple__add_more_container']['multiple__add_more_items'] = [
+      '#type' => 'number',
+      '#title' => $this->t('Number of add more items'),
+      '#required' => TRUE,
+      '#min' => 1,
+      '#max' => 20,
+    ];
+
+    /* Wrapper attributes */
+
+    $form['wrapper_attributes'] = [
+      '#type' => 'details',
+      '#title' => ($this->hasProperty('wrapper_type')) ?
+        $this->t('Wrapper type and attributes') :
+        $this->t('Wrapper attributes'),
+    ];
+    $form['wrapper_attributes']['wrapper_type'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Wrapper type'),
+      '#options' => [
+        'fieldset' => $this->t('Fieldset'),
+        'form_element' => $this->t('Form element'),
+        'container' => $this->t('Container'),
+      ],
+      '#description' => '<b>' . t('Fieldset') . ':</b> ' . t('Wraps inputs in a fieldset.') . ' <strong>' . t('Recommended') . '</strong>' .
+        '<br/><br/><b>' . t('Form element') . ':</b> ' . t('Wraps inputs in a basic form element with title and description.') .
+        '<br/><br/><b>' . t('Container') . ':</b> ' . t('Wraps inputs in a basic div with no title or description.'),
+    ];
+    // Hide element description and display when using a container wrapper.
+    if ($this->hasProperty('wrapper_type')) {
+      $form['element_description']['#states'] = [
+        '!visible' => [
+          ':input[name="properties[wrapper_type]"]' => ['value' => 'container'],
+        ],
+      ];
+      $form['form']['display_container']['#states'] = [
+        '!visible' => [
+          ':input[name="properties[wrapper_type]"]' => ['value' => 'container'],
+        ],
+      ];
+      $form['form']['field_container']['#states'] = [
+        '!visible' => [
+          ':input[name="properties[wrapper_type]"]' => ['value' => 'container'],
+        ],
+      ];
+    }
+
+    $form['wrapper_attributes']['wrapper_attributes'] = [
+      '#type' => 'webform_element_attributes',
+      '#title' => $this->t('Wrapper'),
+      '#class__description' => $this->t("Apply classes to the element's wrapper around both the field and its label. Select 'custom…' to enter custom classes."),
+      '#style__description' => $this->t("Apply custom styles to the element's wrapper around both the field and its label."),
+      '#attributes__description' => $this->t("Enter additional attributes to be added to the element's wrapper."),
+      '#classes' => $this->configFactory->get('webform.settings')->get('element.wrapper_classes'),
+    ];
+
+    /* Element attributes */
+
+    $form['element_attributes'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Element attributes'),
+    ];
+    $form['element_attributes']['attributes'] = [
+      '#type' => 'webform_element_attributes',
+      '#title' => $this->t('Element'),
+      '#classes' => $this->configFactory->get('webform.settings')->get('element.classes'),
+    ];
+
+    /* Label attributes */
+
+    $form['label_attributes'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Label attributes'),
+    ];
+    $form['label_attributes']['label_attributes'] = [
+      '#type' => 'webform_element_attributes',
+      '#title' => $this->t('Label'),
+      '#class__description' => $this->t("Apply classes to the element's label."),
+      '#style__description' => $this->t("Apply custom styles to the element's label."),
+      '#attributes__description' => $this->t("Enter additional attributes to be added to the element's label."),
+    ];
+    // Only display label attribute when the wrapper type is a form element.
+    if ($this->hasProperty('wrapper_type')) {
+      $form['label_attributes']['#states'] = [
+        'visible' => [
+          ':input[name="properties[wrapper_type]"]' => ['value' => 'form_element'],
+        ],
+      ];
+    }
+
+    /* Summary attributes */
+
+    $form['summary_attributes'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Summary attributes'),
+    ];
+    $form['summary_attributes']['summary_attributes'] = [
+      '#type' => 'webform_element_attributes',
+      '#title' => $this->t('Summary'),
+      '#class__description' => $this->t("Apply classes to the details' summary around both the field and its label."),
+      '#style__description' => $this->t("Apply custom styles to the details' summary."),
+      '#attributes__description' => $this->t("Enter additional attributes to be added to the details' summary."),
+    ];
+
+    /* Submission display */
+    $has_edit_twig_access = WebformTwigExtension::hasEditTwigAccess();
+
+    $form['display'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Submission display'),
+    ];
+    // Item.
+    $form['display']['item'] = [
+      '#type' => 'fieldset',
+      '#title' => $this->t('Single item'),
+    ];
+    $form['display']['item']['format'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Item format'),
+      '#description' => $this->t('Select how a single value is displayed.'),
+      '#options' => WebformOptionsHelper::appendValueToText($this->getItemFormats()),
+    ];
+    $format = isset($element_properties['format']) ? $element_properties['format'] : NULL;
+    $format_custom = ($has_edit_twig_access || $format === 'custom');
+    if ($format_custom) {
+      $form['display']['item']['format']['#options'] += ['custom' => $this->t('Custom…')];
+    }
+    $format_custom_states = [
+      'visible' => [':input[name="properties[format]"]' => ['value' => 'custom']],
+      'required' => [':input[name="properties[format]"]' => ['value' => 'custom']],
+    ];
+    $form['display']['item']['format_html'] = [
+      '#type' => 'webform_codemirror',
+      '#mode' => 'twig',
+      '#title' => $this->t('Item format custom HTML'),
+      '#description' => $this->t('The HTML to display for a single element value. You may include HTML or <a href=":href">Twig</a>. You may enter data from the submission as per the "variables" below.', [':href' => 'http://twig.sensiolabs.org/documentation']),
+      '#states' => $format_custom_states,
+      '#access' => $format_custom,
+    ];
+    $form['display']['item']['format_text'] = [
+      '#type' => 'webform_codemirror',
+      '#mode' => 'twig',
+      '#title' => $this->t('Item format custom Text'),
+      '#description' => $this->t('The text to display for a single element value. You may include <a href=":href">Twig</a>. You may enter data from the submission as per the "variables" below.', [':href' => 'http://twig.sensiolabs.org/documentation']),
+      '#states' => $format_custom_states,
+      '#access' => $format_custom,
+    ];
+    if ($has_edit_twig_access) {
+      // Containers use the 'children' variable and inputs use the
+      // 'value' variable.
+      $twig_variables = ($this instanceof ContainerBase) ? ['children' => '{{ children }}'] : ['value' => '{{ value }}'];
+
+      // Composite Twig variables.
+      if ($this instanceof WebformCompositeBase) {
+        // Add composite elements to items.
+        $composite_elements = $this->getCompositeElements();
+        foreach ($composite_elements as $composite_key => $composite_element) {
+          $twig_variables["element.$composite_key"] = "{{ element.$composite_key }}";
+        }
+      }
+
+      $formats = $this->getItemFormats();
+      foreach ($formats as $format_name => $format) {
+        if (is_array($format)) {
+          foreach ($format as $sub_format_name => $sub_format) {
+            $twig_variables["item['$sub_format_name']"] = "{{ item['$sub_format_name'] }}";
+          }
+        }
+        else {
+          $twig_variables["item.$format_name"] = "{{ item.$format_name }}";
+        }
+      }
+      $form['display']['item']['twig'] = WebformTwigExtension::buildTwigHelp($twig_variables);
+      $form['display']['item']['twig']['#states'] = $format_custom_states;
+      WebformElementHelper::setPropertyRecursive($form['display']['item']['twig'], '#access', TRUE);
+    }
+
+    // Items.
+    $form['display']['items'] = [
+      '#type' => 'fieldset',
+      '#title' => $this->t('Multiple items'),
+      '#states' => [
+        'visible' => [
+          [':input[name="properties[multiple][container][cardinality]"]' => ['value' => '-1']],
+          'or',
+          [':input[name="properties[multiple][container][cardinality_number]"]' => ['!value' => 1]],
+        ],
+      ],
+    ];
+    $form['display']['items']['format_items'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Items format'),
+      '#description' => $this->t('Select how multiple values are displayed.'),
+      '#options' => WebformOptionsHelper::appendValueToText($this->getItemsFormats()),
+    ];
+    $format_items = isset($element_properties['format_items']) ? $element_properties['format_items'] : NULL;
+    $format_items_custom = ($has_edit_twig_access || $format_items === 'custom');
+    if ($format_items_custom) {
+      $form['display']['items']['format_items']['#options'] += ['custom' => $this->t('Custom…')];
+    }
+    $format_items_custom_states = [
+      'visible' => [':input[name="properties[format_items]"]' => ['value' => 'custom']],
+      'required' => [':input[name="properties[format_items]"]' => ['value' => 'custom']],
+    ];
+    $form['display']['items']['format_items_html'] = [
+      '#type' => 'webform_codemirror',
+      '#mode' => 'twig',
+      '#title' => $this->t('Items format custom HTML'),
+      '#description' => $this->t('The HTML to display for multiple element values. You may include HTML or <a href=":href">Twig</a>. You may enter data from the submission as per the "variables" below.', [':href' => 'http://twig.sensiolabs.org/documentation']),
+      '#states' => $format_items_custom_states,
+      '#access' => $format_items_custom,
+    ];
+    $form['display']['items']['format_items_text'] = [
+      '#type' => 'webform_codemirror',
+      '#mode' => 'twig',
+      '#title' => $this->t('Items format custom Text'),
+      '#description' => $this->t('The text to display for multiple element values. You may include <a href=":href">Twig</a>. You may enter data from the submission as per the "variables" below.', [':href' => 'http://twig.sensiolabs.org/documentation']),
+      '#states' => $format_items_custom_states,
+      '#access' => $format_items_custom,
+    ];
+    if ($format_items_custom) {
+      $twig_variables = [
+        '{{ value }}',
+        '{{ items }}',
+      ];
+      $form['display']['items']['twig'] = WebformTwigExtension::buildTwigHelp($twig_variables);
+      $form['display']['items']['twig']['#states'] = $format_items_custom_states;
+      WebformElementHelper::setPropertyRecursive($form['display']['items']['twig'], '#access', TRUE);
+    }
+
+    $form['display']['format_attributes'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Display wrapper attributes'),
+    ];
+    $form['display']['format_attributes']['format_attributes'] = [
+      '#type' => 'webform_element_attributes',
+      '#title' => $this->t('Display'),
+      '#class__description' => $this->t("Apply classes to the element's display wrapper. Select 'custom…' to enter custom classes."),
+      '#style__description' => $this->t("Apply custom styles to the element's display wrapper."),
+      '#attributes__description' => $this->t("Enter additional attributes to be added to the element's display wrapper."),
+      '#classes' => $this->configFactory->get('webform.settings')->get('element.wrapper_classes'),
+    ];
+
+    /* Administration */
+
+    $form['admin'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Administration'),
+    ];
+    $form['admin']['private'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Private'),
+      '#description' => $this->t('Private elements are shown only to users with results access.'),
+      '#weight' => 50,
+      '#return_value' => TRUE,
+    ];
+    $form['admin']['admin_title'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Admin title'),
+      '#description' => $this->t('The admin title will always be displayed when managing elements and viewing & downloading submissions.') .
+        '<br/>' .
+        $this->t("If an element's title is hidden, the element's admin title will be displayed when viewing a submission."),
+    ];
+
+    /**************************************************************************/
+    // Access.
+    /**************************************************************************/
+
+    /* Access */
+
+    $operations = [
+      'create' => [
+        '#title' => $this->t('Create submission'),
+        '#description' => $this->t('Select roles and users that should be able to populate this element when creating a new submission.'),
+        '#open' => TRUE,
+      ],
+      'update' => [
+        '#title' => $this->t('Update submission'),
+        '#description' => $this->t('Select roles and users that should be able to update this element when updating an existing submission.'),
+        '#open' => FALSE,
+      ],
+      'view' => [
+        '#title' => $this->t('View submission'),
+        '#description' => $this->t('Select roles and users that should be able to view this element when viewing a submission.'),
+        '#open' => FALSE,
+      ],
+    ];
+
+    $form['access'] = [
+      '#type' => 'container',
+    ];
+    if (!$this->currentUser->hasPermission('administer webform') && !$this->currentUser->hasPermission('administer webform element access')) {
+      $form['access']['#access'] = FALSE;
+    }
+    foreach ($operations as $operation => $operation_element) {
+      $form['access']['access_' . $operation] = $operation_element + [
+        '#type' => 'details',
+      ];
+      $form['access']['access_' . $operation]['access_' . $operation . '_roles'] = [
+        '#type' => 'webform_roles',
+        '#title' => $this->t('Roles'),
+      ];
+      $form['access']['access_' . $operation]['access_' . $operation . '_users'] = [
+        '#type' => 'webform_users',
+        '#title' => $this->t('Users'),
+      ];
+      $form['access']['access_' . $operation]['access_' . $operation . '_permissions'] = [
+        '#type' => 'webform_permissions',
+        '#title' => $this->t('Permissions'),
+        '#multiple' => TRUE,
+        '#select2' => TRUE,
+      ];
+    }
+
+    /**************************************************************************/
+
+    // Disable #multiple if the element has submission data.
+    if (!$form_object->isNew() && $this->hasProperty('multiple')) {
+      $element_key = $form_object->getKey();
+      if ($this->submissionStorage->hasSubmissionValue($webform, $element_key)) {
+        $form['element']['multiple']['#disabled'] = TRUE;
+        $form['element']['multiple']['#description'] = '<em>' . $this->t('There is data for this element in the database. This setting can no longer be changed.') . '</em>';
+      }
+    }
+
+    // Add warning to all password elements that are stored in the database.
+    if (strpos($this->pluginId, 'password') !== FALSE && !$webform->getSetting('results_disabled')) {
+      $form['element']['password_message'] = [
+        '#type' => 'webform_message',
+        '#message_type' => 'warning',
+        '#message_message' => $this->t('Webform submissions store passwords as plain text.') . ' ' .
+          $this->t('<a href=":href">Encryption</a> should be enabled for this element.', [':href' => 'https://www.drupal.org/project/webform_encrypt']),
+        '#access' => TRUE,
+        '#weight' => -100,
+        '#message_close' => TRUE,
+        '#message_storage' => WebformMessage::STORAGE_SESSION,
+      ];
+    }
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $default_properties = $this->getDefaultProperties();
+    $element_properties = WebformArrayHelper::removePrefix($this->configuration)
+      + $default_properties;
+
+    // Make sure 'format_items' is removed if the element does not
+    // support multiple values.
+    // @todo Webform 8.x-6.x: Remove and assume custom element are fixed.
+    if (!$this->supportsMultipleValues()) {
+      unset(
+        $default_properties['format_items'],
+        $default_properties['format_items_html'],
+        $default_properties['format_items_text']
+      );
+    }
+
+    // Set default and element properties.
+    // Note: Storing this information in the webform's state allows modules to view
+    // and alter this information using webform alteration hooks.
+    $form_state->set('default_properties', $default_properties);
+    $form_state->set('element_properties', $element_properties);
+
+    $form = $this->form($form, $form_state);
+    \Drupal::moduleHandler()->alter('webform_element_configuration_form', $form, $form_state);
+
+    // Get default and element properties which can be altered by WebformElementHandlers.
+    // @see \Drupal\webform\Plugin\WebformElement\WebformEntityReferenceTrait::form
+    $element_properties = $form_state->get('element_properties');
+
+    // Copy element properties to custom properties which will be determined
+    // as the default values are set.
+    $custom_properties = $element_properties;
+
+    // Populate the webform.
+    $this->setConfigurationFormDefaultValueRecursive($form, $custom_properties);
+
+    // Set fieldset weights so that they appear first.
+    foreach ($form as &$element) {
+      if (is_array($element) && !isset($element['#weight']) && isset($element['#type']) && $element['#type'] == 'fieldset') {
+        $element['#weight'] = -20;
+      }
+    }
+
+    // Store 'type' as a hardcoded value and make sure it is always first.
+    // Also always remove the 'webform_*' prefix from the type name.
+    if (isset($custom_properties['type'])) {
+      $form['type'] = [
+        '#type' => 'value',
+        '#value' => $custom_properties['type'],
+        '#parents' => ['properties', 'type'],
+      ];
+      unset($custom_properties['type']);
+    }
+
+    // Allow custom properties (i.e. #attributes) to be added to the element.
+    $form['custom'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Custom settings'),
+      '#open' => $custom_properties ? TRUE : FALSE,
+      '#access' => $this->currentUser->hasPermission('edit webform source'),
+    ];
+    if ($api_url = $this->getPluginApiUrl()) {
+      $t_args = [
+        ':href' => $api_url->toString(),
+        '%label' => $this->getPluginLabel(),
+      ];
+      $form['custom']['#description'] = $this->t('Read the %label element\'s <a href=":href">API documentation</a>.', $t_args);
+    }
+
+    $form['custom']['properties'] = [
+      '#type' => 'webform_codemirror',
+      '#mode' => 'yaml',
+      '#title' => $this->t('Custom properties'),
+      '#description' => $this->t('Properties do not have to be prepended with a hash (#) character, the hash character will be automatically added to the custom properties.') .
+        '<br /><br />' .
+        $this->t('These properties and callbacks are not allowed: @properties', ['@properties' => WebformArrayHelper::toString(WebformArrayHelper::addPrefix(WebformElementHelper::$ignoredProperties))]),
+      '#default_value' => $custom_properties ,
+      '#parents' => ['properties', 'custom'],
+    ];
+
+    $this->tokenManager->elementValidate($form);
+
+    // Set custom properties.
+    // Note: Storing this information in the webform's state allows modules to
+    // view and alter this information using webform alteration hooks.
+    $form_state->set('custom_properties', $custom_properties);
+
+    return $this->buildConfigurationFormTabs($form, $form_state);
+  }
+
+  /**
+   * Get form--inline container which is used for side-by-side element layout.
+   *
+   * @return array
+   *   A container element with .form--inline class if inline help text is
+   *   enabled.
+   */
+  protected function getFormInlineContainer() {
+    $help_enabled = $this->configFactory->get('webform.settings')->get('ui.description_help');
+    return [
+      '#type' => 'container',
+      '#attributes' => ($help_enabled) ? ['class' => ['form--inline', 'clearfix', 'webform-ui-element-form-inline--input']] : [],
+    ];
+  }
+
+  /**
+   * Build configuration form tabs.
+   *
+   * @param array $form
+   *   An associative array containing the initial structure of the plugin form.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The current state of the form.
+   *
+   * @return array
+   *   The plugin form with tabs.
+   */
+  protected function buildConfigurationFormTabs(array $form, FormStateInterface $form_state) {
+    $tabs = [
+      'conditions' => [
+        'title' => $this->t('Conditions'),
+        'elements' => [
+          'conditional_logic',
+        ],
+        'weight' => 10,
+      ],
+      'advanced' => [
+        'title' => $this->t('Advanced'),
+        'elements' => [
+          'default',
+          'multiple',
+          'wrapper_attributes',
+          'element_attributes',
+          'label_attributes',
+          'summary_attributes',
+          'display',
+          'admin',
+          'options_properties',
+          'custom',
+        ],
+        'weight' => 20,
+      ],
+      'access' => [
+        'title' => $this->t('Access'),
+        'elements' => [
+          'access',
+        ],
+        'weight' => 30,
+      ],
+    ];
+    return WebformFormHelper::buildTabs($form, $tabs, $form_state->get('active_tab'));
+  }
+
+  /**
+   * Set configuration webform default values recursively.
+   *
+   * @param array $form
+   *   A webform render array.
+   * @param array $element_properties
+   *   The element's properties without hash prefix. Any property that is found
+   *   in the webform will be populated and unset from
+   *   $element_properties array.
+   *
+   * @return bool
+   *   TRUE is the webform has any inputs.
+   */
+  protected function setConfigurationFormDefaultValueRecursive(array &$form, array &$element_properties) {
+    $has_input = FALSE;
+
+    foreach ($form as $property_name => &$property_element) {
+      // Skip all properties.
+      if (is_string($property_name) && Element::property($property_name)) {
+        continue;
+      }
+
+      // Skip Entity reference element 'selection_settings'.
+      // @see \Drupal\webform\Plugin\WebformElement\WebformEntityReferenceTrait::form
+      // @todo Fix entity reference Ajax and move code WebformEntityReferenceTrait.
+      if (!empty($property_element['#tree']) && $property_name == 'selection_settings') {
+        unset($element_properties[$property_name]);
+        $property_element['#parents'] = ['properties', $property_name];
+        $has_input = TRUE;
+        continue;
+      }
+
+      // Determine if the property element is an input using the webform element
+      // manager.
+      // Note: #access is used to protect inputs and containers that should
+      // always be visible.
+      $is_input = $this->elementManager->getElementInstance($property_element)->isInput($property_element);
+      if ($is_input) {
+        if (array_key_exists($property_name, $element_properties)) {
+          // If this property exists, then set its default value.
+          $this->setConfigurationFormDefaultValue($form, $element_properties, $property_element, $property_name);
+          $has_input = TRUE;
+        }
+        elseif (empty($form[$property_name]['#access'])) {
+          // Else completely remove the property element from the webform.
+          unset($form[$property_name]);
+        }
+      }
+      else {
+        // Recurse down this container and see if it's children have inputs.
+        $container_has_input = $this->setConfigurationFormDefaultValueRecursive($property_element, $element_properties);
+        if ($container_has_input) {
+          $has_input = TRUE;
+        }
+        elseif (empty($form[$property_name]['#access'])) {
+          unset($form[$property_name]);
+        }
+      }
+    }
+
+    return $has_input;
+  }
+
+  /**
+   * Set an element's configuration webform element default value.
+   *
+   * @param array $form
+   *   An element's configuration webform.
+   * @param array $element_properties
+   *   The element's properties without hash prefix.
+   * @param array $property_element
+   *   The webform input used to set an element's property.
+   * @param string $property_name
+   *   THe property's name.
+   */
+  protected function setConfigurationFormDefaultValue(array &$form, array &$element_properties, array &$property_element, $property_name) {
+    $default_value = $element_properties[$property_name];
+    $type = (isset($property_element['#type'])) ? $property_element['#type'] : NULL;
+
+    switch ($type) {
+      case 'entity_autocomplete':
+        $target_type = $property_element['#target_type'];
+        $target_storage = $this->entityTypeManager->getStorage($target_type);
+        if (!empty($property_element['#tags'])) {
+          $property_element['#default_value'] = ($default_value) ? $target_storage->loadMultiple($default_value) : [];
+        }
+        else {
+          $property_element['#default_value'] = ($default_value) ? $target_storage->load($default_value) : NULL;
+        }
+        break;
+
+      case 'radios':
+      case 'select':
+        // Handle invalid default_value throwing
+        // "An illegal choice has been detected…" error.
+        if (!is_array($default_value) && isset($property_element['#options'])) {
+          $flattened_options = OptGroup::flattenOptions($property_element['#options']);
+          if (!isset($flattened_options[$default_value])) {
+            $default_value = NULL;
+          }
+        }
+        $property_element['#default_value'] = $default_value;
+        break;
+
+      default:
+        // Convert default_value array into a comma delimited list.
+        // This is applicable to elements that support #multiple #options.
+        if (is_array($default_value) && $property_name == 'default_value' && !$this->isComposite()) {
+          $property_element['#default_value'] = implode(', ', $default_value);
+        }
+        elseif (is_bool($default_value) && $property_name == 'default_value') {
+          $property_element['#default_value'] = $default_value ? 1 : 0;
+        }
+        elseif (is_null($default_value) && $property_name == 'default_value') {
+          $property_element['#default_value'] = (string) $default_value;
+        }
+        else {
+          $property_element['#default_value'] = $default_value;
+        }
+        break;
+
+    }
+
+    $property_element['#parents'] = ['properties', $property_name];
+    unset($element_properties[$property_name]);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+    $properties = $this->getConfigurationFormProperties($form, $form_state);
+
+    $ignored_properties = WebformElementHelper::getIgnoredProperties($properties);
+    foreach ($ignored_properties as $ignored_property => $ignored_message) {
+      // Display custom messages.
+      if ($ignored_property != $ignored_message) {
+        unset($ignored_properties[$ignored_property]);
+        $form_state->setErrorByName('custom', $ignored_message);
+      }
+    }
+
+    // Display ignored properties message.
+    if ($ignored_properties) {
+      $t_args = [
+        '@properties' => WebformArrayHelper::toString($ignored_properties),
+      ];
+      $form_state->setErrorByName('custom', $this->t('Element contains ignored/unsupported properties: @properties', $t_args));
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+    // Generally, elements will not be processing any submitted properties.
+    // It is possible that a custom element might need to call a third-party API
+    // to 'register' the element.
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfigurationFormProperties(array &$form, FormStateInterface $form_state) {
+    $element_properties = $form_state->getValues();
+
+    // Get default properties so that they can be unset below.
+    $default_properties = $form_state->get('default_properties');
+
+    // Get custom properties.
+    if (isset($element_properties['custom'])) {
+      if (is_array($element_properties['custom'])) {
+        $element_properties += $element_properties['custom'];
+      }
+      unset($element_properties['custom']);
+    }
+
+    // Remove all hash prefixes so that we can filter out any default
+    // properties.
+    WebformArrayHelper::removePrefix($element_properties);
+
+    // Build a temp element used to see if multiple value and/or composite
+    // elements need to be supported.
+    $element = WebformArrayHelper::addPrefix($element_properties);
+    foreach ($element_properties as $property_name => $property_value) {
+      if (!array_key_exists($property_name, $default_properties)) {
+        continue;
+      }
+
+      $this->getConfigurationFormProperty($element_properties, $property_name, $property_value, $element);
+
+      // Unset element property that matched the default property.
+      switch ($property_name) {
+        case 'multiple':
+          // The #multiple property element is converted to the correct datatype
+          // so we are looking for 'strict equality' (===).
+          // This prevents #multiple: 2 from being interpeted as TRUE.
+          // @see \Drupal\webform\Element\WebformElementMultiple::validateWebformElementMultiple
+          // @see \Drupal\webform\Plugin\WebformElement\Checkboxes::defaultProperties
+          if ($default_properties[$property_name] === $element_properties[$property_name]) {
+            unset($element_properties[$property_name]);
+          }
+          break;
+
+        default:
+          // Most elements properties are strings or numbers and we need to use
+          // 'type-converting equality' (==) because all numbers are posted
+          // back to the server as strings.
+          if ($default_properties[$property_name] == $element_properties[$property_name]) {
+            unset($element_properties[$property_name]);
+          }
+
+          // Cast data types (except #multiple).
+          if (isset($element_properties[$property_name])) {
+            if (is_bool($default_properties[$property_name])) {
+              $element_properties[$property_name] = (bool) $element_properties[$property_name];
+            }
+            elseif (is_null($default_properties[$property_name]) || is_numeric($default_properties[$property_name])) {
+              $value = $element_properties[$property_name];
+              $cast_value = ($value == (int) $value) ? (int) $value : (float) $value;
+              if ($value == $cast_value) {
+                $element_properties[$property_name] = $cast_value;
+              }
+            }
+          }
+          break;
+      }
+    }
+
+    // Make sure #type is always first.
+    if (isset($element_properties['type'])) {
+      $element_properties = ['type' => $element_properties['type']] + $element_properties;
+    }
+
+    return WebformArrayHelper::addPrefix($element_properties);
+  }
+
+  /**
+   * Get configuration property value.
+   *
+   * @param array $properties
+   *   An associative array of submitted properties.
+   * @param string $property_name
+   *   The property's name.
+   * @param mixed $property_value
+   *   The property's value.
+   * @param array $element
+   *   The element whose properties are being updated.
+   */
+  protected function getConfigurationFormProperty(array &$properties, $property_name, $property_value, array $element) {
+    if ($property_name == 'default_value' && is_string($property_value) && $property_value && $this->hasMultipleValues($element)) {
+      $properties[$property_name] = preg_split('/\s*,\s*/', $property_value);
+    }
+  }
+
+  /**
+   * Determine if the element has a composite field wrapper.
+   *
+   * @return bool
+   *   TRUE if the element has a composite field wrapper.
+   */
+  protected function hasCompositeFormElementWrapper() {
+    $callbacks = $this->elementInfo->getInfoProperty($this->getPluginId(), '#pre_render') ?: [];
+    foreach ($callbacks as $callback) {
+      if (is_array($callback)
+        && in_array($callback[1], ['preRenderCompositeFormElement', 'preRenderWebformCompositeFormElement'])) {
+        return TRUE;
+      }
+    }
+    return FALSE;
+  }
+
+}
diff --git a/web/modules/webform/src/Plugin/WebformHandler/RemotePostWebformHandler.php b/web/modules/webform/src/Plugin/WebformHandler/RemotePostWebformHandler.php
index c035b612e5..d583f219c1 100644
--- a/web/modules/webform/src/Plugin/WebformHandler/RemotePostWebformHandler.php
+++ b/web/modules/webform/src/Plugin/WebformHandler/RemotePostWebformHandler.php
@@ -80,6 +80,20 @@ class RemotePostWebformHandler extends WebformHandlerBase {
    */
   protected $elementManager;
 
+  /**
+   * The current request.
+   *
+   * @var \Symfony\Component\HttpFoundation\Request
+   */
+  protected $request;
+
+  /**
+   * The DrupalKernel instance used in the test.
+   *
+   * @var \Drupal\Core\DrupalKernel
+   */
+  protected $kernel;
+
   /**
    * List of unsupported webform submission properties.
    *
@@ -107,7 +121,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
+    $instance = new static(
       $configuration,
       $plugin_id,
       $plugin_definition,
@@ -121,6 +135,11 @@ public static function create(ContainerInterface $container, array $configuratio
       $container->get('webform.message_manager'),
       $container->get('plugin.manager.webform.element')
     );
+
+    $instance->request = $container->get('request_stack')->getCurrentRequest();
+    $instance->kernel = $container->get('kernel');
+
+    return $instance;
   }
 
   /**
@@ -979,6 +998,11 @@ protected function handleError($state, $message, $request_url, $request_method,
         $error_url = $base_url . preg_replace('#^' . $base_path . '#', '/', $error_url);
       }
       $response = new TrustedRedirectResponse($error_url);
+      // Save the session so things like messages get saved.
+      $this->request->getSession()->save();
+      $response->prepare($this->request);
+      // Make sure to trigger kernel events.
+      $this->kernel->terminate($this->request, $response);
       $response->send();
     }
   }
diff --git a/web/modules/webform/src/Plugin/WebformHandlerPluginCollection.php b/web/modules/webform/src/Plugin/WebformHandlerPluginCollection.php
index 125204f048..c2571d1174 100644
--- a/web/modules/webform/src/Plugin/WebformHandlerPluginCollection.php
+++ b/web/modules/webform/src/Plugin/WebformHandlerPluginCollection.php
@@ -14,8 +14,13 @@ class WebformHandlerPluginCollection extends DefaultLazyPluginCollection {
    * {@inheritdoc}
    */
   public function sortHelper($a_id, $b_id) {
-    $a_weight = $this->get($a_id)->getWeight();
-    $b_weight = $this->get($b_id)->getWeight();
+    /** @var \Drupal\webform\Plugin\WebformHandlerInterface $a */
+    $a = $this->get($a_id);
+    /** @var \Drupal\webform\Plugin\WebformHandlerInterface $b */
+    $b = $this->get($b_id);
+
+    $a_weight = $a->getWeight();
+    $b_weight = $b->getWeight();
     if ($a_weight == $b_weight) {
       return 0;
     }
diff --git a/web/modules/webform/src/Plugin/WebformVariantPluginCollection.php b/web/modules/webform/src/Plugin/WebformVariantPluginCollection.php
index 954cb9978f..fad0e20672 100644
--- a/web/modules/webform/src/Plugin/WebformVariantPluginCollection.php
+++ b/web/modules/webform/src/Plugin/WebformVariantPluginCollection.php
@@ -14,10 +14,15 @@ class WebformVariantPluginCollection extends DefaultLazyPluginCollection {
    * {@inheritdoc}
    */
   public function sortHelper($a_id, $b_id) {
-    $a_weight = $this->get($a_id)->getWeight();
-    $b_weight = $this->get($b_id)->getWeight();
+    /** @var \Drupal\webform\Plugin\WebformVariantInterface $a */
+    $a = $this->get($a_id);
+    /** @var \Drupal\webform\Plugin\WebformVariantInterface $b */
+    $b = $this->get($b_id);
+
+    $a_weight = $a->getWeight();
+    $b_weight = $b->getWeight();
     if ($a_weight == $b_weight) {
-      return 0;
+      return strnatcasecmp($a->getVariantId(), $b->getVariantId());
     }
 
     return ($a_weight < $b_weight) ? -1 : 1;
diff --git a/web/modules/webform/src/Routing/WebformUncacheableResponse.php b/web/modules/webform/src/Routing/WebformUncacheableResponse.php
new file mode 100644
index 0000000000..cdb68373ef
--- /dev/null
+++ b/web/modules/webform/src/Routing/WebformUncacheableResponse.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Drupal\webform\Routing;
+
+use Symfony\Component\HttpFoundation\Response;
+
+/**
+ * Provides an uncacheable response.
+ */
+class WebformUncacheableResponse extends Response {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct($url, $status = 302, $headers = []) {
+    parent::__construct($url, $status, $headers);
+    $this->setPrivate();
+    $this->setMaxAge(0);
+    $this->setSharedMaxAge(0);
+    $this->headers->addCacheControlDirective('must-revalidate', TRUE);
+    $this->headers->addCacheControlDirective('no-store', TRUE);
+  }
+
+}
diff --git a/web/modules/webform/src/Utility/WebformElementHelper.php b/web/modules/webform/src/Utility/WebformElementHelper.php
index 0711cdd1bb..382843af17 100644
--- a/web/modules/webform/src/Utility/WebformElementHelper.php
+++ b/web/modules/webform/src/Utility/WebformElementHelper.php
@@ -31,37 +31,22 @@ class WebformElementHelper {
     // Properties that will cause unpredictable rendering.
     '#weight' => '#weight',
     // Callbacks are blocked to prevent unwanted code executions.
+    '#access_callback' => '#access_callback',
+    '#ajax' => '#ajax',
     '#after_build' => '#after_build',
     '#element_validate' => '#element_validate',
+    '#lazy_builder' => '#lazy_builder',
     '#post_render' => '#post_render',
     '#pre_render' => '#pre_render',
     '#process' => '#process',
     '#submit' => '#submit',
     '#validate' => '#validate',
     '#value_callback' => '#value_callback',
-  ];
-
-  /**
-   * Ignored element sub properties used by composite elements.
-   *
-   * @var array
-   */
-  public static $ignoredSubProperties = [
-    // Properties that will allow code injection.
-    '#allowed_tags' => '#allowed_tags',
-    // Properties that will break webform data handling.
-    '#tree' => '#tree',
-    '#array_parents' => '#array_parents',
-    '#parents' => '#parents',
-    // Callbacks are blocked to prevent unwanted code executions.
-    '#after_build' => '#after_build',
-    '#element_validate' => '#element_validate',
-    '#post_render' => '#post_render',
-    '#pre_render' => '#pre_render',
-    '#process' => '#process',
-    '#submit' => '#submit',
-    '#validate' => '#validate',
-    '#value_callback' => '#value_callback',
+    // Element specific callbacks.
+    '#file_value_callbacks' => '#file_value_callbacks',
+    '#date_date_callbacks' => '#date_date_callbacks',
+    '#date_time_callbacks' => '#date_time_callbacks',
+    '#captcha_validate' => '#captcha_validate',
   ];
 
   /**
@@ -371,7 +356,12 @@ public static function getIgnoredProperties(array $element) {
     foreach ($element as $key => $value) {
       if (Element::property($key)) {
         if (self::isIgnoredProperty($key)) {
-          $ignored_properties[$key] = $key;
+          // Computed elements use #ajax as boolean and should not be ignored.
+          // @see \Drupal\webform\Element\WebformComputedBase
+          $is_ajax_computed = ($key === '#ajax' && is_bool($value));
+          if (!$is_ajax_computed) {
+            $ignored_properties[$key] = $key;
+          }
         }
         elseif ($key == '#element' && is_array($value) && isset($element['#type']) && $element['#type'] === 'webform_composite') {
           foreach ($value as $composite_value) {
@@ -410,7 +400,15 @@ public static function getIgnoredProperties(array $element) {
   public static function removeIgnoredProperties(array $element) {
     foreach ($element as $key => $value) {
       if (Element::property($key) && self::isIgnoredProperty($key)) {
-        unset($element[$key]);
+        // Computed elements use #ajax as boolean and should not be ignored.
+        // @see \Drupal\webform\Element\WebformComputedBase
+        $is_ajax_computed = ($key === '#ajax' && is_bool($value));
+        if (!$is_ajax_computed) {
+          unset($element[$key]);
+        }
+      }
+      elseif (is_array($value)) {
+        $element[$key] = static::removeIgnoredProperties($value);
       }
     }
     return $element;
@@ -419,7 +417,8 @@ public static function removeIgnoredProperties(array $element) {
   /**
    * Determine if an element's property should be ignored.
    *
-   * Subelement properties are delimited using __.
+   * - Subelement properties are delimited using __.
+   * - All _validation and _callback properties are ignored.
    *
    * @param string $property
    *   A property name.
@@ -433,7 +432,7 @@ public static function removeIgnoredProperties(array $element) {
   protected static function isIgnoredProperty($property) {
     // Build cached ignored sub properties regular expression.
     if (!isset(self::$ignoredSubPropertiesRegExp)) {
-      self::$ignoredSubPropertiesRegExp = '/__(' . implode('|', array_keys(WebformArrayHelper::removePrefix(self::$ignoredSubProperties))) . ')$/';
+      self::$ignoredSubPropertiesRegExp = '/__(' . implode('|', array_keys(WebformArrayHelper::removePrefix(self::$ignoredProperties))) . ')$/';
     }
 
     if (isset(self::$ignoredProperties[$property])) {
@@ -442,6 +441,9 @@ protected static function isIgnoredProperty($property) {
     elseif (strpos($property, '__') !== FALSE && preg_match(self::$ignoredSubPropertiesRegExp, $property)) {
       return TRUE;
     }
+    elseif (preg_match('/_(validates?|callbacks?)$/', $property)) {
+      return TRUE;
+    }
     else {
       return FALSE;
     }
diff --git a/web/modules/webform/src/Utility/WebformOptionsHelper.php b/web/modules/webform/src/Utility/WebformOptionsHelper.php
index 5f3b449d53..ca54b10e50 100644
--- a/web/modules/webform/src/Utility/WebformOptionsHelper.php
+++ b/web/modules/webform/src/Utility/WebformOptionsHelper.php
@@ -97,7 +97,8 @@ public static function getOptionsText(array $values, array $options) {
   public static function getOptionText($value, array $options, $options_description = FALSE) {
     foreach ($options as $option_value => $option_text) {
       if (is_array($option_text)) {
-        if ($option_text = self::getOptionText($value, $option_text, $options_description)) {
+        $option_text = self::getOptionText($value, $option_text, $options_description);
+        if ((string) $value !== (string) $option_text) {
           return $option_text;
         }
       }
diff --git a/web/modules/webform/src/WebformAddonsManager.php b/web/modules/webform/src/WebformAddonsManager.php
index d8c8b036fa..92c0a60aed 100644
--- a/web/modules/webform/src/WebformAddonsManager.php
+++ b/web/modules/webform/src/WebformAddonsManager.php
@@ -190,6 +190,14 @@ protected function initProjects() {
       'category' => 'element',
     ];
 
+    // Element: Webform Attachment Gated Download.
+    $projects['webform_attachment_gated_download'] = [
+      'title' => $this->t('Webform Attachment Gated Download'),
+      'description' => $this->t('Provides a field formatter for file, image, and media types which links to a webform.'),
+      'url' => Url::fromUri('https://www.drupal.org/project/webform_attachment_gated_download'),
+      'category' => 'element',
+    ];
+
     // Element: Webform Handsontable.
     $projects['handsontable_yml_webform'] = [
       'title' => $this->t('Webform Handsontable'),
@@ -298,6 +306,14 @@ protected function initProjects() {
       'category' => 'enhancement',
     ];
 
+    // Enhancement: Webform Calculation.
+    $projects['webform_calculation'] = [
+      'title' => $this->t('Webform Calculation'),
+      'description' => $this->t('Provides ability to make dynamic calculations using Webform.'),
+      'url' => Url::fromUri('https://www.drupal.org/project/webform_calculation'),
+      'category' => 'enhancement',
+    ];
+
     // Enhancement: Webform Confirmation File.
     $projects['webform_confirmation_file'] = [
       'title' => $this->t('Webform Confirmation File'),
@@ -527,7 +543,7 @@ protected function initProjects() {
     $projects['graphql_webform'] = [
       'title' => $this->t('GraphQL Webform'),
       'description' => $this->t('Provides GraphQL integration with the Webform module.'),
-      'url' => Url::fromUri('https://github.com/duartegarin/graphql_webform'),
+      'url' => Url::fromUri('https://www.drupal.org/project/graphql_webform'),
       'category' => 'integration',
     ];
 
diff --git a/web/modules/webform/src/WebformEntityElementsValidator.php b/web/modules/webform/src/WebformEntityElementsValidator.php
index 7799e4db87..8ac9030231 100644
--- a/web/modules/webform/src/WebformEntityElementsValidator.php
+++ b/web/modules/webform/src/WebformEntityElementsValidator.php
@@ -275,7 +275,7 @@ protected function validateNames() {
         break;
 
       case 'a-z0-9_-':
-        $machine_name_requirement = $this->t('lowercase letters, numbers, and underscores');
+        $machine_name_requirement = $this->t('lowercase letters, numbers, underscores, and dashes');
         break;
 
       case 'a-zA-Z0-9_-':
@@ -504,6 +504,16 @@ protected function validateHierarchy() {
       elseif (!$webform_element->isContainer($element) && !empty($element['#webform_children'])) {
         $messages[] = $this->t('The %title (@type) is a webform element that can not have any child elements.', $t_args);
       }
+      elseif ($plugin_id === 'webform_table_row') {
+        $parent_element = ($element['#webform_parent_key']) ? $elements[$element['#webform_parent_key']] : NULL;
+        if (!$parent_element || !isset($parent_element['#type']) || $parent_element['#type'] !== 'webform_table') {
+          $t_args += [
+            '%parent_title' => $this->t('Table'),
+            '@parent_type' => 'webform_table',
+          ];
+          $messages[] = $this->t('The %title (@type) must be with in a %parent_title (@parent_type) element.', $t_args);
+        }
+      }
     }
     return $messages;
   }
diff --git a/web/modules/webform/src/WebformEntityListBuilder.php b/web/modules/webform/src/WebformEntityListBuilder.php
index d91c959342..866fd3f3e1 100644
--- a/web/modules/webform/src/WebformEntityListBuilder.php
+++ b/web/modules/webform/src/WebformEntityListBuilder.php
@@ -608,7 +608,7 @@ protected function isAdmin() {
    * {@inheritdoc}
    */
   protected function ensureDestination(Url $url) {
-    // Never add add a destination to operation URLs.
+    // Never add a destination to operation URLs.
     return $url;
   }
 
diff --git a/web/modules/webform/src/WebformHelpManager.php b/web/modules/webform/src/WebformHelpManager.php
index 8dc4bd5872..8bb6583be1 100644
--- a/web/modules/webform/src/WebformHelpManager.php
+++ b/web/modules/webform/src/WebformHelpManager.php
@@ -1290,6 +1290,12 @@ protected function initVideos() {
           ],
         ],
       ],
+      'composites_vs_tables' => [
+        'title' => $this->t('Webform Composites vs. Tables'),
+        'content' => $this->t('This screencast walks through when to use a webform composite element and when to use a webform table.'),
+        'youtube_id' => '7cVIqySy5fs',
+        'presentation_id' => '1R13ZGkNgTkxjlN-BT05zrwW2JKhOcvGiByNYl7qtywg',
+      ],
 
       'webform' => [
         'title' => $this->t('Webform: There is this for that'),
diff --git a/web/modules/webform/src/WebformLibrariesManager.php b/web/modules/webform/src/WebformLibrariesManager.php
index 771aff09e8..64d743576f 100644
--- a/web/modules/webform/src/WebformLibrariesManager.php
+++ b/web/modules/webform/src/WebformLibrariesManager.php
@@ -359,8 +359,8 @@ protected function initLibraries() {
       'description' => $this->t("A jQuery plugin for entering and validating international telephone numbers. It adds a flag dropdown to any input, detects the user's country, displays a relevant placeholder and provides formatting/validation methods."),
       'notes' => $this->t('International Telephone Input is used by the Telephone element.'),
       'homepage_url' => Url::fromUri('https://github.com/jackocnr/intl-tel-input'),
-      'download_url' => Url::fromUri('https://github.com/jackocnr/intl-tel-input/archive/v16.0.0.zip'),
-      'version' => '16.0.0',
+      'download_url' => Url::fromUri('https://github.com/jackocnr/intl-tel-input/archive/v16.1.0.zip'),
+      'version' => '16.1.0',
     ];
     $libraries['jquery.rateit'] = [
       'title' => $this->t('jQuery: RateIt'),
diff --git a/web/modules/webform/src/WebformOptionsForm.php b/web/modules/webform/src/WebformOptionsForm.php
index ca56675dbd..0c468f9edf 100644
--- a/web/modules/webform/src/WebformOptionsForm.php
+++ b/web/modules/webform/src/WebformOptionsForm.php
@@ -10,12 +10,29 @@
 use Drupal\webform\Utility\WebformArrayHelper;
 use Drupal\webform\Utility\WebformDialogHelper;
 use Drupal\webform\Utility\WebformOptionsHelper;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Provides a form to set options.
  */
 class WebformOptionsForm extends EntityForm {
 
+  /**
+   * Module extension list.
+   *
+   * @var \Drupal\Core\Extension\ModuleExtensionList
+   */
+  protected $moduleExtensionList;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    $instance = parent::create($container);
+    $instance->moduleExtensionList = $container->get('extension.list.module');
+    return $instance;
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -162,7 +179,7 @@ protected function alterModuleNames() {
 
     $hook_name = 'webform_options_' . $webform_options->id() . '_alter';
     $alter_hooks = $this->moduleHandler->getImplementations($hook_name);
-    $module_info = system_get_info('module');
+    $module_info = $this->moduleExtensionList->getAllInstalledInfo();
     $module_names = [];
     foreach ($alter_hooks as $options_alter_hook) {
       $module_name = str_replace($hook_name, '', $options_alter_hook);
diff --git a/web/modules/webform/src/WebformSubmissionForm.php b/web/modules/webform/src/WebformSubmissionForm.php
index b720cd54b6..c9848666ff 100644
--- a/web/modules/webform/src/WebformSubmissionForm.php
+++ b/web/modules/webform/src/WebformSubmissionForm.php
@@ -27,6 +27,7 @@
 use Drupal\webform\Form\WebformDialogFormTrait;
 use Drupal\webform\Plugin\WebformElement\Hidden;
 use Drupal\webform\Plugin\WebformElement\OptionsBase;
+use Drupal\webform\Plugin\WebformElement\WebformCompositeBase;
 use Drupal\webform\Plugin\WebformElementEntityReferenceInterface;
 use Drupal\webform\Plugin\WebformElementManagerInterface;
 use Drupal\webform\Plugin\WebformElementOtherInterface;
@@ -311,7 +312,7 @@ protected function getWrapperId() {
    * {@inheritdoc}
    *
    * This is the best place to override an entity form's default settings
-   * because is is called immediately after the form object is initialized.
+   * because it is called immediately after the form object is initialized.
    *
    * @see \Drupal\Core\Entity\EntityFormBuilder::getForm
    */
@@ -1751,41 +1752,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
     }
 
     // Validate file (upload) limit.
-    // @see \Drupal\webform\Plugin\WebformElement\WebformManagedFileBase::validateManagedFileLimit
-    $file_limit = $this->getWebform()->getSetting('form_file_limit')
-      ?: $this->configFactory->get('webform.settings')->get('settings.default_form_file_limit')
-      ?: '';
-    $file_limit = Bytes::toInt($file_limit);
-    if (!$file_limit) {
-      return;
-    }
-
-    // Validate file upload limit.
-    $file_names = [];
-    $total_file_size = 0;
-    $element_keys = $this->getWebform()->getElementsManagedFiles();
-    foreach ($element_keys as $element_key) {
-      $data = $this->entity->getElementData($element_key);
-      if ($data) {
-        $fids = (array) $data;
-        /** @var \Drupal\file\FileInterface[] $files */
-        $files = $this->entityTypeManager->getStorage('file')->loadMultiple($fids);
-        foreach ($files as $file) {
-          $total_file_size += (int) $file->getSize();
-          $file_names[] = $file->getFilename() . ' - ' . format_size($file->getSize(), $this->entity->language()->getId());
-        }
-      }
-    }
-    if ($total_file_size > $file_limit) {
-      $t_args = ['%quota' => format_size($file_limit)];
-      $message = [];
-      $message['content'] = ['#markup' => $this->t("This form's file upload quota of %quota has been exceeded. Please remove some files.", $t_args)];
-      $message['files'] = [
-        '#theme' => 'item_list',
-        '#items' => $file_names,
-      ];
-      $form_state->setErrorByName(NULL, $this->renderer->renderPlain($message));
-    }
+    $this->validateUploadedManagedFiles($form, $form_state);
   }
 
   /**
@@ -1947,6 +1914,97 @@ public function reset(array &$form, FormStateInterface $form_state) {
     $this->rebuild($form, $form_state);
   }
 
+  /****************************************************************************/
+  // Validate functions.
+  /****************************************************************************/
+
+  /**
+   * Validate uploaded managed file limits.
+   *
+   * @param array $form
+   *   An associative array containing the structure of the form.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The current state of the form.
+   *
+   * @see \Drupal\webform\Plugin\WebformElement\WebformManagedFileBase::validateManagedFileLimit
+   */
+  protected function validateUploadedManagedFiles(array $form, FormStateInterface $form_state) {
+    $file_limit = $this->getWebform()->getSetting('form_file_limit')
+      ?: $this->configFactory->get('webform.settings')->get('settings.default_form_file_limit')
+      ?: '';
+    $file_limit = Bytes::toInt($file_limit);
+    if (!$file_limit) {
+      return;
+    }
+
+    // Validate file upload limit.
+    $fids = $this->getUploadedManagedFileIds();
+    if (!$fids) {
+      return;
+    }
+    $file_names = [];
+    $total_file_size = 0;
+
+    /** @var \Drupal\file\FileInterface[] $files */
+    $files = $this->entityTypeManager->getStorage('file')->loadMultiple($fids);
+    foreach ($files as $file) {
+      $total_file_size += (int) $file->getSize();
+      $file_names[] = $file->getFilename() . ' - ' . format_size($file->getSize(), $this->entity->language()->getId());
+    }
+
+    if ($total_file_size > $file_limit) {
+      $t_args = ['%quota' => format_size($file_limit)];
+      $message = [];
+      $message['content'] = ['#markup' => $this->t("This form's file upload quota of %quota has been exceeded. Please remove some files.", $t_args)];
+      $message['files'] = [
+        '#theme' => 'item_list',
+        '#items' => $file_names,
+      ];
+      $form_state->setErrorByName(NULL, $this->renderer->renderPlain($message));
+    }
+  }
+
+  /**
+   * Get uploaded managed file ids.
+   *
+   * @return array
+   *   An array of uploaded file ids.
+   */
+  protected function getUploadedManagedFileIds() {
+    $fids = [];
+
+    $element_keys = $this->getWebform()->getElementsManagedFiles();
+    foreach ($element_keys as $element_key) {
+      $data = $this->entity->getElementData($element_key);
+      if (!$data) {
+        continue;
+      }
+
+      $element = $this->getWebform()->getElement($element_key);
+      $element_plugin = $this->elementManager->getElementInstance($element);
+      $multiple = $element_plugin->hasMultipleValues($element);
+
+      // Get fids from composite sub-elements.
+      if ($element_plugin instanceof WebformCompositeBase) {
+        $managed_file_keys = $element_plugin->getManagedFiles($element);
+        // Convert single composite value to array of multiple composite values.
+        $data = (!$multiple) ? [$data] : $data;
+        foreach ($data as $item) {
+          foreach ($managed_file_keys as $manage_file_key) {
+            if ($item[$manage_file_key]) {
+              $fids[] = $item[$manage_file_key];
+            }
+          }
+        }
+      }
+      else {
+        $fids = array_merge($fids, (array) $data);
+      }
+    }
+
+    return $fids;
+  }
+
   /****************************************************************************/
   // Webform functions
   /****************************************************************************/
@@ -2119,10 +2177,14 @@ protected function displayCurrentPage(array &$form, FormStateInterface $form_sta
     if ($current_page == 'webform_preview') {
       // Hide all elements except 'webform_actions'.
       foreach ($form['elements'] as $element_key => $element) {
-        if (isset($element['#type']) && $element['#type'] == 'webform_actions') {
+        if (isset($element['#type']) && $element['#type'] === 'webform_actions') {
           continue;
         }
-        $form['elements'][$element_key]['#access'] = FALSE;
+
+        // Set #access to FALSE which will suppresses webform #required validation.
+        if (Element::child($element_key) && is_array($form['elements'])) {
+          WebformElementHelper::setPropertyRecursive($form['elements'][$element_key], '#access', FALSE);
+        }
       }
 
       // Display preview message.
@@ -2431,13 +2493,7 @@ protected function prepopulateData(array &$data) {
     }
 
     // Set prepopulate data.
-    if ($this->operation === 'test') {
-      // Query string data should override existing test data.
-      $data = $prepopulate_data + $data;
-    }
-    else {
-      $data += $prepopulate_data;
-    }
+    $data = $prepopulate_data + $data;
   }
 
   /**
diff --git a/web/modules/webform/src/WebformSubmissionListBuilder.php b/web/modules/webform/src/WebformSubmissionListBuilder.php
index 9fc81e818d..21a466842a 100644
--- a/web/modules/webform/src/WebformSubmissionListBuilder.php
+++ b/web/modules/webform/src/WebformSubmissionListBuilder.php
@@ -432,7 +432,7 @@ public function render() {
         '%webform' => $this->webform->label(),
         '%user' => $this->account->getDisplayName(),
       ];
-      if ($this->state == self::STATE_DRAFT) {
+      if ($this->draft) {
         $build['#title'] = $this->t('Drafts for %webform for %user', $t_args);
       }
       else {
@@ -496,10 +496,7 @@ protected function buildSubmissionViews() {
     // Populate the views arguments.
     $arguments = [];
     foreach ($display_arguments as $argument_name => $display_argument) {
-      if ($display_argument['table'] !== 'webform_submission') {
-        $arguments[] = 'all';
-      }
-      else {
+      if ($display_argument['table'] === 'webform_submission') {
         switch ($argument_name) {
           case 'webform_id':
             $arguments[] = (isset($this->webform)) ? $this->webform->id() : 'all';
@@ -726,7 +723,7 @@ protected function buildCustomizeButton() {
    *   A render array representing the information summary.
    */
   protected function buildInfo() {
-    if ($this->account && $this->state == self::STATE_DRAFT) {
+    if ($this->draft) {
       $info = $this->formatPlural($this->total, '@total draft', '@total drafts', ['@total' => $this->total]);
     }
     else {
diff --git a/web/modules/webform/src/WebformSubmissionStorage.php b/web/modules/webform/src/WebformSubmissionStorage.php
index 9d7d9037e9..3338d84341 100644
--- a/web/modules/webform/src/WebformSubmissionStorage.php
+++ b/web/modules/webform/src/WebformSubmissionStorage.php
@@ -1161,24 +1161,27 @@ public function delete(array $entities) {
     // @see \Drupal\webform\Plugin\WebformElement\WebformSignature
     foreach ($entities as $entity) {
       $webform = $entity->getWebform();
-      $stream_wrappers = array_keys(\Drupal::service('stream_wrapper_manager')
-        ->getNames(StreamWrapperInterface::WRITE_VISIBLE));
-      foreach ($stream_wrappers as $stream_wrapper) {
-        $file_directory = $stream_wrapper . '://webform/' . $webform->id() . '/' . $entity->id();
-        // Clear empty webform submission directory.
-        if (file_exists($file_directory)
-          && empty(file_scan_directory($file_directory, '/.*/'))) {
-          $this->fileSystem->deleteRecursive($file_directory);
+      if ($webform) {
+        $stream_wrappers = array_keys(\Drupal::service('stream_wrapper_manager')
+          ->getNames(StreamWrapperInterface::WRITE_VISIBLE));
+        foreach ($stream_wrappers as $stream_wrapper) {
+          $file_directory = $stream_wrapper . '://webform/' . $webform->id() . '/' . $entity->id();
+          // Clear empty webform submission directory.
+          if (file_exists($file_directory)
+            && empty(file_scan_directory($file_directory, '/.*/'))) {
+            $this->fileSystem->deleteRecursive($file_directory);
+          }
         }
       }
     }
 
     // Log deleted.
     foreach ($entities as $entity) {
+      $webform = $entity->getWebform();
       \Drupal::logger('webform')
         ->notice('Deleted @form: Submission #@id.', [
           '@id' => $entity->id(),
-          '@form' => $entity->getWebform()->label(),
+          '@form' => ($webform) ? $webform->label() : '[' . t('Webform') . ']',
         ]);
     }
 
@@ -1194,7 +1197,9 @@ public function delete(array $entities) {
    */
   public function invokeWebformHandlers($method, WebformSubmissionInterface $webform_submission, &$context1 = NULL, &$context2 = NULL) {
     $webform = $webform_submission->getWebform();
-    return $webform->invokeHandlers($method, $webform_submission, $context1, $context2);
+    if ($webform) {
+      return $webform->invokeHandlers($method, $webform_submission, $context1, $context2);
+    }
   }
 
   /**
@@ -1202,7 +1207,9 @@ public function invokeWebformHandlers($method, WebformSubmissionInterface $webfo
    */
   public function invokeWebformElements($method, WebformSubmissionInterface $webform_submission, &$context1 = NULL, &$context2 = NULL) {
     $webform = $webform_submission->getWebform();
-    $webform->invokeElements($method, $webform_submission, $context1, $context2);
+    if ($webform) {
+      $webform->invokeElements($method, $webform_submission, $context1, $context2);
+    }
   }
 
   /****************************************************************************/
@@ -1370,7 +1377,9 @@ protected function loadData(array &$webform_submissions) {
         $sid = $record['sid'];
         $name = $record['name'];
 
-        $elements = $webform_submissions[$sid]->getWebform()->getElementsInitializedFlattenedAndHasValue();
+        /** @var \Drupal\webform\WebformInterface $webform */
+        $webform = $webform_submissions[$sid]->getWebform();
+        $elements = ($webform) ? $webform->getElementsInitializedFlattenedAndHasValue() : [];
         $element = (isset($elements[$name])) ? $elements[$name] : ['#webform_multiple' => FALSE, '#webform_composite' => FALSE];
 
         if ($element['#webform_composite']) {
diff --git a/web/modules/webform/src/WebformSubmissionStorageSchema.php b/web/modules/webform/src/WebformSubmissionStorageSchema.php
index c3705f9aba..96151fa959 100644
--- a/web/modules/webform/src/WebformSubmissionStorageSchema.php
+++ b/web/modules/webform/src/WebformSubmissionStorageSchema.php
@@ -16,6 +16,10 @@ class WebformSubmissionStorageSchema extends SqlContentEntityStorageSchema {
   protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) {
     $schema = parent::getEntitySchema($entity_type, $reset);
 
+    $schema['webform_submission']['indexes'] += [
+      'webform_submission_field__token' => ['token'],
+    ];
+
     $schema['webform_submission_data'] = [
       'description' => 'Stores all submitted data for webform submissions.',
       'fields' => [
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax.yml
index 94adcab0e3..21ccee432f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax.yml
@@ -133,6 +133,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -183,3 +184,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_inline.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_inline.yml
index 1565116c3c..2eeba8cbfd 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_inline.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_inline.yml
@@ -134,6 +134,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -184,3 +185,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_message.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_message.yml
index 2b38380ad9..6a33ff18c1 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_message.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_message.yml
@@ -134,6 +134,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -184,3 +185,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_modal.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_modal.yml
index 88ea11db54..b4b00eab61 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_modal.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_modal.yml
@@ -134,6 +134,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -184,3 +185,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_page.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_page.yml
index b0f4954e9e..d336b2747c 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_page.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_page.yml
@@ -134,6 +134,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -184,3 +185,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url.yml
index 436eea45ec..619a30003e 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url.yml
@@ -131,6 +131,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -181,3 +182,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url_msg.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url_msg.yml
index ecdcae2dea..4865f70fe5 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url_msg.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url_msg.yml
@@ -134,6 +134,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -184,3 +185,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite.yml
index 58f8f1eab1..276565c8c7 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite.yml
@@ -217,6 +217,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -275,3 +276,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_custom.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_custom.yml
index a3b79623d8..895672b275 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_custom.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_custom.yml
@@ -179,6 +179,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -237,3 +238,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_custom_file.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_custom_file.yml
index 1b4b3d1613..67a5d535e7 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_custom_file.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_custom_file.yml
@@ -150,6 +150,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -208,3 +209,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_format.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_format.yml
index 52866437e1..b6137bf194 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_format.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_format.yml
@@ -455,7 +455,7 @@ elements: |
           q2: 1
           q3: 1
         '#format': table
-
+  
 css: ''
 javascript: ''
 settings:
@@ -569,6 +569,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -691,3 +692,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_format_multiple.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_format_multiple.yml
index 01437c36e5..ec7347a253 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_format_multiple.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_format_multiple.yml
@@ -711,7 +711,7 @@ elements: |
             phone: '+1 212-333-4444'
             ext: 0
         '#format_items': table
-
+  
 css: ''
 javascript: ''
 settings:
@@ -825,6 +825,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -947,3 +948,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_inline.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_inline.yml
index d9cd456e05..93e30b3554 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_inline.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_inline.yml
@@ -134,6 +134,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -184,3 +185,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_message.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_message.yml
index 810e7212c4..380dfd7fc9 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_message.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_message.yml
@@ -134,6 +134,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -184,3 +185,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_modal.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_modal.yml
index 63824dad68..9cca671181 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_modal.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_modal.yml
@@ -134,6 +134,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -184,3 +185,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_none.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_none.yml
index dc5e9cd175..f42ac3c790 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_none.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_none.yml
@@ -134,6 +134,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -184,3 +185,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page.yml
index 60b0e61374..c992d8f984 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page.yml
@@ -134,6 +134,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -184,3 +185,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page_custom.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page_custom.yml
index 79c65736af..046f32ff43 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page_custom.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page_custom.yml
@@ -137,6 +137,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -187,3 +188,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url.yml
index 74476b14b9..223e133640 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url.yml
@@ -131,6 +131,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -181,3 +182,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url_message.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url_message.yml
index 4f46df4311..d8a9e18d38 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url_message.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url_message.yml
@@ -134,6 +134,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -184,3 +185,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element.yml
index fd2b2fe33d..36480b028f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element.yml
@@ -351,6 +351,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -401,3 +402,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_access.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_access.yml
index 2a08c37f65..fb6eadcef4 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_access.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_access.yml
@@ -219,6 +219,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: true
 access:
@@ -273,3 +274,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_actions.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_actions.yml
index 866e84373a..7b1e7c913b 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_actions.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_actions.yml
@@ -138,6 +138,7 @@ elements: |
     '#draft_hide': true
     '#wizard_prev_hide': true
     '#wizard_next_hide': true
+  
 css: ''
 javascript: ''
 settings:
@@ -251,6 +252,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -301,3 +303,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_actions_buttons.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_actions_buttons.yml
index 6bf959df67..9bb87039fc 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_actions_buttons.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_actions_buttons.yml
@@ -58,7 +58,7 @@ elements: |
       class:
         - preview_next_button_attributes
       style: 'color: orange'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -172,6 +172,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -222,3 +223,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_address.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_address.yml
index 8760c9c77a..ed713393b7 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_address.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_address.yml
@@ -184,6 +184,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -242,3 +243,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_allowed_tags.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_allowed_tags.yml
index 21eeef6106..4697c41032 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_allowed_tags.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_allowed_tags.yml
@@ -133,6 +133,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -183,3 +184,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_attributes.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_attributes.yml
index 30f54ce297..f93db6a6e9 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_attributes.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_attributes.yml
@@ -147,6 +147,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -205,3 +206,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_autocomplete.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_autocomplete.yml
index 63718abe76..bfb392a1e7 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_autocomplete.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_autocomplete.yml
@@ -151,6 +151,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -201,3 +202,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_captcha.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_captcha.yml
index 4661574550..15edeea26f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_captcha.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_captcha.yml
@@ -154,6 +154,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -212,3 +213,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkbox.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkbox.yml
index 4cdd44d7a2..b0c4158f69 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkbox.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkbox.yml
@@ -31,6 +31,7 @@ elements: |
     '#title': checkbox_return_value_raw
     '#return_value': custom_return_value_raw
     '#format': raw
+  
 css: ''
 javascript: ''
 settings:
@@ -144,6 +145,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -202,3 +204,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkbox_value.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkbox_value.yml
index e03b17c112..c787921c5e 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkbox_value.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkbox_value.yml
@@ -34,7 +34,7 @@ elements: |
         One: One
         Two: Two
         Three: Three
-
+  
 css: ''
 javascript: ''
 settings:
@@ -148,6 +148,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -206,3 +207,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkboxes.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkboxes.yml
index 868eea01f2..c393baafc7 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkboxes.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkboxes.yml
@@ -308,6 +308,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -366,3 +367,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_codemirror.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_codemirror.yml
index 679425a688..890079bed3 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_codemirror.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_codemirror.yml
@@ -53,6 +53,13 @@ elements: |
       one: One
       two: Two
       three: Three
+  yaml_decode_value:
+    '#type': webform_codemirror
+    '#mode': yaml
+    '#title': yaml_decode_value
+    '#decode_value': true
+    '#description': 'Always decode the value'
+    '#default_value': 'test: hello'
   html_basic:
     '#type': webform_codemirror
     '#mode': html
@@ -85,16 +92,16 @@ elements: |
           </script>
         </body>
       </html>
-  
+
   twig_basic:
     '#type': webform_codemirror
     '#mode': twig
     '#title': twig_basic
     '#default_value': |
-  
+
       {% set value = "Hello" %}
       {{ value }}
-  
+
 css: ''
 javascript: ''
 settings:
@@ -208,6 +215,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -266,3 +274,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_composite.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_composite.yml
index 90ad3a6672..35a45f5477 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_composite.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_composite.yml
@@ -171,6 +171,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -229,3 +230,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_composite_wrapper.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_composite_wrapper.yml
index 9a8f9eed00..21daebba50 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_composite_wrapper.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_composite_wrapper.yml
@@ -247,6 +247,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -305,3 +306,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_ajax.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_ajax.yml
index 765e80e8ae..dda816af2f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_ajax.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_ajax.yml
@@ -204,6 +204,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -262,3 +263,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_debug.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_debug.yml
index a3342684bf..e066ab8dfe 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_debug.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_debug.yml
@@ -264,6 +264,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -314,3 +315,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_token.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_token.yml
index ee95216371..cb458ac62e 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_token.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_token.yml
@@ -184,6 +184,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -242,3 +243,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_twig.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_twig.yml
index 18d6aaa71a..4fef3f6bf3 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_twig.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_twig.yml
@@ -211,6 +211,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -261,3 +262,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_container.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_container.yml
index 493c8201f1..aab258ab65 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_container.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_container.yml
@@ -188,6 +188,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -238,3 +239,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_counter.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_counter.yml
index 358d91af39..3cf61b0577 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_counter.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_counter.yml
@@ -47,6 +47,15 @@ elements: |
       '#counter_type': character
       '#counter_maximum': 10
       '#counter_maximum_message': '%d character(s) remaining. This is custom text'
+    counter_characters_xss:
+      '#type': textfield
+      '#title': 'counter_characters_xss'
+      '#counter_type': character
+      '#counter_minimum': 5
+      '#counter_maximum': 10
+      '#counter_minimum_message': '<script>alert(''XSS'');</script><em>%d</em> character(s) entered.'
+      '#counter_maximum_message': '<script>alert(''XSS'');</script><em>%d</em> character(s) remaining.'
+
   counter_word:
     '#type': details
     '#title': counter_word
@@ -193,6 +202,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -251,3 +261,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_date.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_date.yml
index 44fb2a6d3a..a8c617a0e4 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_date.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_date.yml
@@ -82,6 +82,7 @@ elements: |
     '#title': date_datepicker_placeholder
     '#datepicker': true
     '#placeholder': '{date}'
+  
 css: ''
 javascript: ''
 settings:
@@ -195,6 +196,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -253,3 +255,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_datelist.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_datelist.yml
index 881f12b363..90f7215fa0 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_datelist.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_datelist.yml
@@ -209,6 +209,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -267,3 +268,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_datetime.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_datetime.yml
index 8e69b1500c..6cb03e95df 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_datetime.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_datetime.yml
@@ -123,7 +123,7 @@ elements: |
     '#description': |
       @see <a href="https://www.drupal.org/node/2917107">Issue #2917107: Date and Time validation problem</a><br/>
       @see <a href="https://www.drupal.org/node/2723159">Issue #2723159: Datetime form element cannot validate when using a format without seconds</a><br/>
-
+  
     '#date_date_element': datepicker
     '#date_time_element': text
     '#date_time_format': 'H:i'
@@ -153,7 +153,7 @@ elements: |
         '#autocomplete': 'off'
     '#default_value':
       - datetime: '2009-08-18T01:00:00-05:00'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -267,6 +267,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -325,3 +326,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_description_tooltip.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_description_tooltip.yml
index 142840a08f..099f51fdbf 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_description_tooltip.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_description_tooltip.yml
@@ -466,7 +466,7 @@ elements: |
       '#title': 'Machine name'
       '#description': 'This is a description for the ''machine_name'' element.'
       '#description_display': tooltip
-
+  
 css: ''
 javascript: ''
 settings:
@@ -580,6 +580,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -630,3 +631,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_details.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_details.yml
index 7579fc7793..def00d1726 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_details.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_details.yml
@@ -160,6 +160,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -210,3 +211,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_disabled.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_disabled.yml
index 3df5c0b17d..26610a6738 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_disabled.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_disabled.yml
@@ -363,7 +363,7 @@ elements: |
     '#type': webform_video_file
     '#title': 'Video file'
     '#disabled': true
-
+  
 css: ''
 javascript: ''
 settings:
@@ -477,6 +477,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -527,3 +528,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_email_confirm.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_email_confirm.yml
index 1caf90aa32..80bb1cd77a 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_email_confirm.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_email_confirm.yml
@@ -156,6 +156,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -214,3 +215,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_email_multiple.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_email_multiple.yml
index bc1dfa3951..ccc9357b4b 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_email_multiple.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_email_multiple.yml
@@ -141,6 +141,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -199,3 +200,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_entity_autocomplete.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_entity_autocomplete.yml
index 16c578eaf3..2975d4baae 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_entity_autocomplete.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_entity_autocomplete.yml
@@ -179,6 +179,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -237,3 +238,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_entity_reference.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_entity_reference.yml
index f3a70e5bd5..fb960d65ea 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_entity_reference.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_entity_reference.yml
@@ -176,6 +176,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -234,3 +235,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_excluded_columns.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_excluded_columns.yml
index e57f00fe48..aa8f70b2e3 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_excluded_columns.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_excluded_columns.yml
@@ -29,6 +29,7 @@ elements: |
     '#title': webform_excluded_columns
     '#default_value':
       webform_excluded_columns: webform_excluded_columns
+  
 css: ''
 javascript: ''
 settings:
@@ -142,6 +143,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -200,3 +202,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_excluded_elements.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_excluded_elements.yml
index d46b7b1b7e..a8ab2144e5 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_excluded_elements.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_excluded_elements.yml
@@ -37,6 +37,7 @@ elements: |
     '#default_value':
       webform_excluded_elements: webform_excluded_elements
       webform_excluded_elements_markup: webform_excluded_elements_markup
+  
 css: ''
 javascript: ''
 settings:
@@ -150,6 +151,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -208,3 +210,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_fieldset.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_fieldset.yml
index ce46b6cd47..b59dc32bd9 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_fieldset.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_fieldset.yml
@@ -174,6 +174,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -224,3 +225,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox.yml
index 3efad20783..f15c2f203c 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox.yml
@@ -936,7 +936,7 @@ elements: |
     toggle_rating:
       '#type': rating
       '#title': rating
-
+  
 css: ''
 javascript: ''
 settings:
@@ -1050,6 +1050,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -1100,3 +1101,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox_flex.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox_flex.yml
index 0d380b89a0..dbd938e3de 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox_flex.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox_flex.yml
@@ -919,6 +919,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -969,3 +970,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format.yml
index 377cecd60e..04d60d86b2 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format.yml
@@ -1304,7 +1304,7 @@ elements: |
         '#title': 'Machine name (Raw value)'
         '#default_value': loremipsum
         '#format': raw
-
+  
 css: ''
 javascript: ''
 settings:
@@ -1418,6 +1418,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -1540,3 +1541,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_custom.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_custom.yml
index af68e366c3..d097e9b8cf 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_custom.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_custom.yml
@@ -327,6 +327,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -377,3 +378,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_multiple.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_multiple.yml
index 6e8da26f67..085ab5c755 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_multiple.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_multiple.yml
@@ -389,7 +389,6 @@ elements: |
           two: Two
           three: Three
         '#options_display': side_by_side
-        '#multiple': true
         '#default_value':
           - one
           - two
@@ -403,7 +402,6 @@ elements: |
           two: Two
           three: Three
         '#options_display': side_by_side
-        '#multiple': true
         '#default_value':
           - one
           - two
@@ -417,7 +415,6 @@ elements: |
           two: Two
           three: Three
         '#options_display': side_by_side
-        '#multiple': true
         '#default_value':
           - one
           - two
@@ -431,7 +428,6 @@ elements: |
           two: Two
           three: Three
         '#options_display': side_by_side
-        '#multiple': true
         '#default_value':
           - one
           - two
@@ -445,12 +441,23 @@ elements: |
           two: Two
           three: Three
         '#options_display': side_by_side
-        '#multiple': true
         '#default_value':
           - one
           - two
           - three
         '#format_items': ul
+      checkboxes_checklist:
+        '#type': checkboxes
+        '#title': 'Checkboxes (Checklist)'
+        '#options':
+          one: One
+          two: Two
+          three: Three
+        '#default_value':
+          - one
+          - two
+          - three
+        '#format_items': 'checklist:boxes'
     webform_checkboxes_other:
       '#type': details
       '#title': 'Checkboxes other'
@@ -1673,6 +1680,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -1795,3 +1803,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_token.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_token.yml
index 97472c6745..6ff02bb021 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_token.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_token.yml
@@ -26,7 +26,7 @@ elements: |
       - 1
       - 2
       - 3
-
+  
 css: ''
 javascript: ''
 settings:
@@ -140,6 +140,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -218,7 +219,7 @@ handlers:
         <h3>ul:</h3>[webform_submission:values:checkboxes:value:ul]<hr />
         <h3>ol:</h3>[webform_submission:values:checkboxes:value:ol]<hr />
         <h3>raw:</h3>[webform_submission:values:checkboxes:raw]<hr />
-
+        
       excluded_elements: {  }
       ignore_access: false
       exclude_empty: true
@@ -257,25 +258,25 @@ handlers:
       body: |
         default:
         [webform_submission:values:checkboxes]
-
+        
         comma:
         [webform_submission:values:checkboxes:value:comma]
-
+        
         semicolon:
         [webform_submission:values:checkboxes:value:semicolon]
-
+        
         and:
         [webform_submission:values:checkboxes:value:and]
-
+        
         ul:
         [webform_submission:values:checkboxes:value:ul]
-
+        
         ol:
         [webform_submission:values:checkboxes:value:ol]
-
+        
         raw:
         [webform_submission:values:checkboxes:raw]
-
+        
       excluded_elements: {  }
       ignore_access: false
       exclude_empty: true
@@ -291,3 +292,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_help.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_help.yml
index b934abef2e..eae85003dd 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_help.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_help.yml
@@ -246,6 +246,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -296,3 +297,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_help_display.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_help_display.yml
index 2601f248b1..08df870e92 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_help_display.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_help_display.yml
@@ -1909,7 +1909,7 @@ elements: |
       '#help_display': element_after
     machine_name_hr:
       '#type': webform_horizontal_rule
-
+  
 css: ''
 javascript: ''
 settings:
@@ -2023,6 +2023,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -2073,6 +2074,7 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
 uuid: 28d4e7be-efdb-4a88-bc0d-16ed5e8a1767
 _core:
   default_config_hash: n-o0dubYyFAYHV9OGOrntyVrFt0L6owQM3jhd_cjuIc
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_horizontal_rule.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_horizontal_rule.yml
index 2f2b718626..4ff05e0110 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_horizontal_rule.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_horizontal_rule.yml
@@ -215,6 +215,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -273,3 +274,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_editor.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_editor.yml
index b254dfeee6..40ab375b6c 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_editor.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_editor.yml
@@ -155,6 +155,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -213,3 +214,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_escape.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_escape.yml
index 89a2c60f58..a360b3a3ee 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_escape.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_escape.yml
@@ -524,7 +524,7 @@ elements: |
     table:
       '#type': table
       '#title': 'Table | <script>alert(''This markup is not escaped properly!!!'') </script>'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -638,6 +638,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -688,3 +689,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_markup.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_markup.yml
index 8f5dac08d9..d85e37c556 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_markup.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_markup.yml
@@ -524,7 +524,7 @@ elements: |
     table:
       '#type': table
       '#title': '<u>Table</u>'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -638,6 +638,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -688,3 +689,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_ignored_properties.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_ignored_properties.yml
index bc98f9e3c8..68aef76d72 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_ignored_properties.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_ignored_properties.yml
@@ -15,21 +15,61 @@ title: 'Test: Element: Ignore properties'
 description: 'Test ignored element properties and callbacks.'
 category: 'Test: Element'
 elements: |
-  test:
+  textfield:
     '#type': textfield
-    '#title': test
+    '#title': textfield
     '#tree': '#tree'
-    '#array_parents': '#array_parents'
-    '#weight': '#weight'
-    '#after_build': '#after_build'
-    '#element_validate': '#element_validate'
-    '#post_render': '#post_render'
-    '#pre_render': '#pre_render'
-    '#process': '#process'
-    '#submit': '#submit'
-    '#validate': '#validate'
-    '#value_callback': '#value_callback'
-  
+    '#array_parents': { }
+    '#weight': 0
+    '#after_build':
+      - 'webform_test_ignored_element_callback'
+    '#element_validate':
+      - 'webform_test_ignored_element_callback'
+    '#post_render':
+      - 'webform_test_ignored_element_callback'
+    '#pre_render':
+      - 'webform_test_ignored_element_callback'
+    '#process':
+      - 'webform_test_ignored_element_callback'
+    '#submit':
+      - 'webform_test_ignored_element_callback'
+    '#validate':
+      - 'webform_test_ignored_element_callback'
+    '#value_callback':
+      - 'webform_test_ignored_element_callback'
+  actions:
+    '#type': actions
+    '#title': actions
+    '#pre_render':
+      - 'webform_test_ignored_element_callback'
+  select_other:
+    '#title': select_other
+    '#type': webform_select_other
+    '#options':
+      One: One
+      Two: Two
+      Three: Three
+    '#other__element_validate':
+      - 'webform_test_ignored_element_callback'
+    '#other__pre_render':
+      - 'webform_test_ignored_element_callback'
+  name:
+    '#title': name
+    '#type': webform_name
+    '#first__element_validate':
+      - 'webform_test_ignored_element_callback'
+    '#first__pre_render':
+      - 'webform_test_ignored_element_callback'
+  custom_composite:
+    '#type': webform_custom_composite
+    '#title': custom_composite
+    '#element':
+      textfield:
+        '#type': textfield
+        '#title': custom_composite_textfield
+        '#pre_render':
+          - 'webform_test_ignored_element_callback'
+
 css: ''
 javascript: ''
 settings:
@@ -143,6 +183,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -193,3 +234,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_file.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_file.yml
index 664504a464..8c2e0a70e1 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_file.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_file.yml
@@ -136,6 +136,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -194,3 +195,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_file_attach.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_file_attach.yml
index 354828d7dc..cc9380b942 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_file_attach.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_file_attach.yml
@@ -20,7 +20,7 @@ elements: |
     '#title': webform_image_file_attachment
     '#file_extensions': gif
     '#attachment_image_style': thumbnail
-
+  
 css: ''
 javascript: ''
 settings:
@@ -134,6 +134,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -220,3 +221,4 @@ handlers:
       sender_name: ''
       theme_name: ''
       parameters: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_resolution.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_resolution.yml
index 351182f690..f7d596b094 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_resolution.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_resolution.yml
@@ -139,6 +139,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -197,3 +198,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_input_mask.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_input_mask.yml
index 4ae28159e7..6be99b84d0 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_input_mask.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_input_mask.yml
@@ -81,6 +81,7 @@ elements: |
     '#type': textfield
     '#title': module
     '#input_mask': '999'
+  
 css: ''
 javascript: ''
 settings:
@@ -194,6 +195,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -252,3 +254,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_invalid.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_invalid.yml
index 89bf01990e..a2ec8d7352 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_invalid.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_invalid.yml
@@ -128,6 +128,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -178,3 +179,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_likert.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_likert.yml
index 55750a3cfe..4a45615dd1 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_likert.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_likert.yml
@@ -192,6 +192,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -250,3 +251,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_loc_places.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_loc_places.yml
index b33cacee8f..4bd2fe9516 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_loc_places.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_loc_places.yml
@@ -183,6 +183,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -241,3 +242,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file.yml
index 9157cddf3e..fb4e07a86e 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file.yml
@@ -178,6 +178,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -228,3 +229,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_dis.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_dis.yml
index 4815bb3a42..6cbf437593 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_dis.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_dis.yml
@@ -133,6 +133,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -183,3 +184,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_help.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_help.yml
index b8c1faa11d..0e074e390b 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_help.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_help.yml
@@ -178,6 +178,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -236,3 +237,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_limit.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_limit.yml
index b6ca2e84b9..153a1914f6 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_limit.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_limit.yml
@@ -27,7 +27,13 @@ elements: |
     '#type': managed_file
     '#title': managed_file_03
     '#file_extensions': txt
-  
+  custom_composite_managed_files:
+    '#type': webform_custom_composite
+    '#title': custom_composite_managed_files
+    '#element':
+      managed_file:
+        '#type': managed_file
+        '#title': managed_file
 css: ''
 javascript: ''
 settings:
@@ -141,6 +147,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -191,3 +198,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_name.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_name.yml
index 784d51732d..fa8c71a29d 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_name.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_name.yml
@@ -145,6 +145,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -203,3 +204,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_prev.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_prev.yml
index faeeaf2853..406dece42e 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_prev.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_prev.yml
@@ -173,6 +173,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -225,3 +226,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_mapping.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_mapping.yml
index a99382c689..bbd523396b 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_mapping.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_mapping.yml
@@ -244,6 +244,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -302,3 +303,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_markup.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_markup.yml
index ddd36a1e0e..18f48ccaa1 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_markup.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_markup.yml
@@ -147,6 +147,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -197,3 +198,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_media_file.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_media_file.yml
index 6703192ebf..e06e765640 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_media_file.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_media_file.yml
@@ -185,6 +185,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -235,3 +236,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_message.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_message.yml
index 1f16d84833..c72efbda30 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_message.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_message.yml
@@ -205,6 +205,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -255,3 +256,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_more.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_more.yml
index 1042e2e957..f02c4d85bc 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_more.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_more.yml
@@ -178,6 +178,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -228,3 +229,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple.yml
index bf1a3ca6d8..a04aa0848e 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple.yml
@@ -392,6 +392,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -450,3 +451,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_date.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_date.yml
index 6f7b5509dc..09576c81d3 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_date.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_date.yml
@@ -153,6 +153,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -211,3 +212,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_property.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_property.yml
index dd86a5c3c2..20cd086492 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_property.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_property.yml
@@ -50,7 +50,7 @@ elements: |
     '#title': webform_element_multiple_custom_access
     '#default_value': 5
     '#access': false
-
+  
 css: ''
 javascript: ''
 settings:
@@ -164,6 +164,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -222,3 +223,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_text.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_text.yml
index a937f1b200..a81415c817 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_text.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_text.yml
@@ -196,6 +196,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -254,3 +255,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_options.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_options.yml
index 87588370e9..5d1f3b79f9 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_options.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_options.yml
@@ -189,6 +189,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -247,3 +248,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_other.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_other.yml
index 0ab2881795..7d8c129442 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_other.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_other.yml
@@ -147,7 +147,7 @@ elements: |
         Two: Two
         Three: Three
       '#wrapper_type': container
-
+  
 css: ''
 javascript: ''
 settings:
@@ -261,6 +261,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -319,3 +320,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_prepopulate.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_prepopulate.yml
index 96188f2620..037a6519b5 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_prepopulate.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_prepopulate.yml
@@ -15,20 +15,38 @@ title: 'Test: Element: Prepopulate'
 description: 'Test prepopulating individual elements using query string parameters.'
 category: 'Test: Element'
 elements: |
-  textfield:
-    '#type': textfield
-    '#title': textfield
-  textfield_prepopulate:
-    '#type': textfield
-    '#title': textfield_prepopulate
-    '#prepopulate': true
-  managed_file_prepopulate:
-    '#type': managed_file
-    '#title': managed_file_prepopulate
-    '#prepopulate': true
-  prepopulate_test:
-    '#markup': '<a href="?textfield=value&textfield_prepopulate=value">?textfield=value&textfield_prepopulate=value</a>'
-  
+  page_01:
+    '#type': webform_wizard_page
+    '#title': page_01
+    textfield_01:
+      '#type': textfield
+      '#title': textfield_01
+    textfield_prepopulate_01:
+      '#type': textfield
+      '#title': textfield_prepopulate_01
+      '#prepopulate': true
+      '#default_value': '{default_value_01}'
+    managed_file_prepopulate_01:
+      '#type': managed_file
+      '#title': managed_file_prepopulate_01
+      '#prepopulate': true
+    prepopulate_test:
+      '#markup': '<a href="?textfield_01=value&textfield_prepopulate_01=value">?textfield_01=value&textfield_prepopulate_01=value</a>'
+  page_02:
+    '#type': webform_wizard_page
+    '#title': page_02
+    textfield_02:
+      '#type': textfield
+      '#title': textfield_02
+    textfield_prepopulate_02:
+      '#type': textfield
+      '#title': textfield_prepopulate_02
+      '#prepopulate': true
+      '#default_value': '{default_value_02}'
+    managed_file_prepopulate_02:
+      '#type': managed_file
+      '#title': managed_file_prepopulate_02
+      '#prepopulate': true
 css: ''
 javascript: ''
 settings:
@@ -142,6 +160,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -192,3 +211,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_private.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_private.yml
index 24b345dc9d..b3f644e90e 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_private.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_private.yml
@@ -143,6 +143,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: true
 access:
@@ -193,3 +194,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_radios.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_radios.yml
index 64bcbdef91..55be033777 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_radios.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_radios.yml
@@ -323,6 +323,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -381,3 +382,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_range.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_range.yml
index f750fbdc7b..1ade023b06 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_range.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_range.yml
@@ -184,6 +184,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -242,3 +243,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_rating.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_rating.yml
index 00f287e2cc..d08724ff0b 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_rating.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_rating.yml
@@ -147,6 +147,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -205,3 +206,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_readonly.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_readonly.yml
index 21536e51f2..ab791a4bdf 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_readonly.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_readonly.yml
@@ -137,6 +137,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -195,3 +196,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_same.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_same.yml
index e8bb4a4de2..06657a66d4 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_same.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_same.yml
@@ -202,6 +202,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -260,3 +261,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_scale.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_scale.yml
new file mode 100644
index 0000000000..85af024b5a
--- /dev/null
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_scale.yml
@@ -0,0 +1,230 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_test
+open: null
+close: null
+weight: 0
+uid: null
+template: false
+archive: false
+id: test_element_scale
+title: 'Test: Element: Scale'
+description: 'Test the scale element.'
+category: 'Test: Element'
+elements: |
+  scale:
+    '#type': webform_scale
+    '#title': scale
+  scale_text:
+    '#type': webform_scale
+    '#title': scale_text
+    '#min': 0
+    '#max': 10
+    '#min_text': '0 = disagree'
+    '#max_text': 'agree = 10'
+  scale_text_above:
+    '#type': webform_scale
+    '#title': scale_text_above
+    '#min': 0
+    '#max': 10
+    '#min_text': '0 = disagree'
+    '#max_text': 'agree = 10'
+    '#scale_text': above
+  scale_small:
+    '#type': webform_scale
+    '#title': scale_small
+    '#scale_size': small
+  scale_medium:
+    '#type': webform_scale
+    '#title': scale_medium
+    '#scale_size': medium
+  scale_large:
+    '#type': webform_scale
+    '#title': scale_large
+    '#scale_size': large
+  scale_square:
+    '#type': webform_scale
+    '#title': scale_square
+    '#scale_type': square
+  scale_flexbox:
+    '#type': webform_scale
+    '#title': scale_flexbox
+    '#scale_type': flexbox
+    '#min_text': '1 = disagree'
+    '#max_text': 'agree = 5'
+css: ''
+javascript: ''
+settings:
+  ajax: false
+  ajax_scroll_top: form
+  ajax_progress_type: ''
+  ajax_effect: ''
+  ajax_speed: null
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  page_admin_theme: false
+  form_title: source_entity_webform
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_remote_addr: true
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_prepopulate_source_entity_required: false
+  form_prepopulate_source_entity_type: ''
+  form_reset: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_disable_inline_errors: false
+  form_required: false
+  form_unsaved: false
+  form_disable_back: false
+  form_submit_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  form_access_denied: default
+  form_access_denied_title: ''
+  form_access_denied_message: ''
+  form_access_denied_attributes: {  }
+  form_file_limit: ''
+  submission_label: ''
+  submission_log: false
+  submission_views: {  }
+  submission_views_replace: {  }
+  submission_user_columns: {  }
+  submission_user_duplicate: false
+  submission_access_denied: default
+  submission_access_denied_title: ''
+  submission_access_denied_message: ''
+  submission_access_denied_attributes: {  }
+  submission_exception_message: ''
+  submission_locked_message: ''
+  submission_excluded_elements: {  }
+  submission_exclude_empty: false
+  submission_exclude_empty_checkbox: false
+  previous_submission_message: ''
+  previous_submissions_message: ''
+  autofill: false
+  autofill_message: ''
+  autofill_excluded_elements: {  }
+  wizard_progress_bar: true
+  wizard_progress_pages: false
+  wizard_progress_percentage: false
+  wizard_progress_link: false
+  wizard_progress_states: false
+  wizard_start_label: ''
+  wizard_preview_link: false
+  wizard_confirmation: true
+  wizard_confirmation_label: ''
+  wizard_track: ''
+  preview: 0
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  preview_attributes: {  }
+  preview_excluded_elements: {  }
+  preview_exclude_empty: true
+  preview_exclude_empty_checkbox: false
+  draft: none
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  draft_pending_single_message: ''
+  draft_pending_multiple_message: ''
+  confirmation_type: message
+  confirmation_title: ''
+  confirmation_message: ''
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  confirmation_exclude_query: false
+  confirmation_exclude_token: false
+  confirmation_update: false
+  limit_total: null
+  limit_total_interval: null
+  limit_total_message: ''
+  limit_total_unique: false
+  limit_user: null
+  limit_user_interval: null
+  limit_user_message: ''
+  limit_user_unique: false
+  entity_limit_total: null
+  entity_limit_total_interval: null
+  entity_limit_user: null
+  entity_limit_user_interval: null
+  purge: none
+  purge_days: null
+  results_disabled: false
+  results_disabled_ignore: false
+  results_customize: false
+  token_view: false
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+    permissions: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  administer:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  test:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  configuration:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+handlers:
+  debug:
+    id: debug
+    label: Debug
+    handler_id: debug
+    status: true
+    conditions: {  }
+    weight: 1
+    settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_section.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_section.yml
index 8808a73a42..e9f5c2f7c6 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_section.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_section.yml
@@ -148,6 +148,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -198,3 +199,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_select.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_select.yml
index 7040ee3d35..738df31bcf 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_select.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_select.yml
@@ -486,6 +486,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -544,3 +545,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_signature.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_signature.yml
index 016a7e187a..e5d5e33be4 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_signature.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_signature.yml
@@ -41,6 +41,7 @@ elements: |
     '#type': webform_signature
     '#title': signature_readonly
     '#readonly': true
+  
 css: ''
 javascript: ''
 settings:
@@ -154,6 +155,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -212,3 +214,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_states.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_states.yml
index 6c6a18cb80..f9395f2922 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_states.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_states.yml
@@ -237,6 +237,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -295,3 +296,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submission_views.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submission_views.yml
index 0d1aa556bf..5da2206a91 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submission_views.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submission_views.yml
@@ -160,6 +160,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -218,3 +219,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submission_views_r.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submission_views_r.yml
index ccf7fd690e..e34bd29a49 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submission_views_r.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submission_views_r.yml
@@ -154,6 +154,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -212,3 +213,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submitted_value.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submitted_value.yml
index 5e0986c65f..b53622701a 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submitted_value.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submitted_value.yml
@@ -168,6 +168,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -226,3 +227,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_table.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_table.yml
index 0ba8f9f207..76e9c2e9f8 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_table.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_table.yml
@@ -52,6 +52,146 @@ elements: |
         '#default_value': Female
       table__2__markup:
         '#markup': '{markup_2}'
+  table_basic:
+    '#type': webform_table
+    '#title': table_basic
+    '#header':
+      - title: 'First Name'
+        attributes: {  }
+      - title: 'Last Name'
+        attributes: {  }
+      - title: Gender
+        attributes: {  }
+      - title: Markup
+    table_basic_01:
+      '#type': webform_table_row
+      '#title': 'Basic Person (1)'
+      table_basic_01_first_name:
+        '#type': textfield
+        '#title': 'First name (1)'
+        '#title_display': invisible
+      table_basic_01_last_name:
+        '#type': textfield
+        '#title': 'Last name (1)'
+        '#title_display': invisible
+      table_basic_01_gender:
+        '#type': select
+        '#title': 'Gender (1)'
+        '#title_display': invisible
+        '#options': gender
+      table_basic_01_markup:
+        '#markup': '{markup_1}'
+  table_advanced:
+    '#type': webform_table
+    '#title': table_advanced
+    '#title_display': invisible
+    '#format': details
+    '#header':
+      - title: Composite
+        attributes:
+          width: 50%
+      - title: Nested
+        attributes:
+          width: 50%
+    '#sticky': true
+    '#caption': '{caption}'
+    table_advanced_01:
+      '#type': webform_table_row
+      '#title': 'Advanced Person (1)'
+      table_advanced_01_address:
+        '#type': webform_address
+        '#title': Address
+        '#admin_title': 'Address (1)'
+      table_advanced_01_container:
+        '#type': container
+        table_advanced_01_first_name:
+          '#type': textfield
+          '#title': 'First name'
+          '#admin_title': 'First name (1)'
+        table_advanced_01_last_name:
+          '#type': textfield
+          '#title': 'Last name'
+          '#admin_title': 'Last name (1)'
+        table_advanced_01_gender:
+          '#type': select
+          '#title': Gender
+          '#options': gender
+          '#admin_title': 'Gender (2)'
+        table_advanced_01_managed_file:
+          '#type': managed_file
+          '#title': Files
+          '#admin_title': 'Files (2)'
+          '#multiple': true
+  table_prefix_children_false:
+    '#type': webform_table
+    '#title': table_prefix_children_false
+    '#prefix_children': false
+    table_prefix_children_false_01:
+      '#type': webform_table_row
+      '#title': table_prefix_children_false_01
+  table_rows:
+    '#type': select
+    '#title': table_rows
+    '#options':
+      1: '1'
+      2: '2'
+      3: '3'
+      4: '4'
+    '#default_value': '1'
+  table_states:
+    '#type': webform_table
+    '#title': table_states
+    '#states':
+      invisible:
+        ':input[name="table_rows"]':
+          value: ''
+    '#header':
+      - title: Item
+        attributes: {  }
+    table_states_01:
+      '#type': webform_table_row
+      '#title': 'item (1)'
+      '#states':
+        visible:
+          ':input[name="table_rows"]':
+            value:
+              greater: '0'
+      table_advanced_01_textfield:
+        '#type': textfield
+        '#title': 'textfield (1)'
+    table_states_02:
+      '#type': webform_table_row
+      '#title': 'item (2)'
+      '#states':
+        visible:
+          ':input[name="table_rows"]':
+            value:
+              greater: '1'
+      table_advanced_02_textfield:
+        '#type': textfield
+        '#title': 'textfield (2)'
+    table_states_03:
+      '#type': webform_table_row
+      '#title': 'item (3)'
+      '#states':
+        visible:
+          ':input[name="table_rows"]':
+            value:
+              greater: '2'
+      table_advanced_03_textfield:
+        '#type': textfield
+        '#title': 'textfield (3)'
+    table_states_04:
+      '#type': webform_table_row
+      '#title': 'item (4)'
+      '#states':
+        visible:
+          ':input[name="table_rows"]':
+            value:
+              greater: '3'
+      table_advanced_04_textfield:
+        '#type': textfield
+        '#title': 'textfield (4)'
 
 css: ''
 javascript: ''
@@ -166,6 +306,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -224,3 +365,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_table_select_sort.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_table_select_sort.yml
index ce99e3ad2e..b887370332 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_table_select_sort.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_table_select_sort.yml
@@ -156,7 +156,7 @@ elements: |
       '#default_value':
         five: five
         three: three
-
+  
 css: ''
 javascript: ''
 settings:
@@ -270,6 +270,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -328,3 +329,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_telephone.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_telephone.yml
index 31b13dd3ab..47624c63cf 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_telephone.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_telephone.yml
@@ -158,6 +158,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -216,3 +217,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_term_reference.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_term_reference.yml
index 47174d38a2..965e21c2e9 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_term_reference.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_term_reference.yml
@@ -210,6 +210,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -260,3 +261,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_terms_of_service.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_terms_of_service.yml
index 7635a593a6..b3d64ca506 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_terms_of_service.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_terms_of_service.yml
@@ -147,6 +147,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -197,3 +198,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_text_format.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_text_format.yml
index 7663466054..0e0fc680d8 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_text_format.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_text_format.yml
@@ -144,6 +144,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -194,3 +195,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_time.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_time.yml
index 3b183b242b..b31b60c28a 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_time.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_time.yml
@@ -67,7 +67,7 @@ elements: |
     '#title': time_timepicker_placeholder
     '#timepicker': true
     '#placeholder': '{time}'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -181,6 +181,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -239,3 +240,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_title_display.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_title_display.yml
index 0e18020faa..758550fb1d 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_title_display.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_title_display.yml
@@ -1513,7 +1513,7 @@ elements: |
       '#title_display': none
     machine_name_hr:
       '#type': webform_horizontal_rule
-
+  
 css: ''
 javascript: ''
 settings:
@@ -1627,6 +1627,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -1685,3 +1686,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_users_roles.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_users_roles.yml
index 9c6430fdff..9aad9bce61 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_users_roles.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_users_roles.yml
@@ -146,6 +146,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -204,3 +205,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_minlength.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_minlength.yml
index 202cd81d04..94a78c800f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_minlength.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_minlength.yml
@@ -140,6 +140,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -190,3 +191,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_multiple.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_multiple.yml
index 9ba5a32b11..528ac6b031 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_multiple.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_multiple.yml
@@ -192,6 +192,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -250,3 +251,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_pattern.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_pattern.yml
index fa12125e42..3c2f967a58 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_pattern.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_pattern.yml
@@ -37,7 +37,7 @@ elements: |
     '#title': pattern_unicode
     '#pattern': \u2E8F
     '#description': 'Enter unicode CJK characters ''⺏'''
-
+  
 css: ''
 javascript: ''
 settings:
@@ -151,6 +151,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -209,3 +210,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_required.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_required.yml
index da2396dec4..3a1e4ebef3 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_required.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_required.yml
@@ -34,7 +34,7 @@ elements: |
       three: Three
     '#required': true
     '#required_error': 'This is a custom required message'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -148,6 +148,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -198,3 +199,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_unique.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_unique.yml
index 0a5fad1a05..819c7f001e 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_unique.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_unique.yml
@@ -55,7 +55,7 @@ elements: |
     '#options':
       1: one
       2: two
-
+  
 css: ''
 javascript: ''
 settings:
@@ -169,6 +169,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -219,3 +220,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_view.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_view.yml
index f6b0562aa5..f616111063 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_view.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_view.yml
@@ -24,7 +24,7 @@ elements: |
     '#display_id': default
     '#arguments':
       - '[webform:id]'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -138,6 +138,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -196,3 +197,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_example_elements.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_example_elements.yml
index 985302f733..a6fb8d7037 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_example_elements.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_example_elements.yml
@@ -510,7 +510,7 @@ elements: |
     table:
       '#type': table
       '#title': Table
-
+  
 css: ''
 javascript: ''
 settings:
@@ -624,6 +624,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -674,3 +675,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_example_elements_composite.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_example_elements_composite.yml
index 92215f8760..62267a4c7b 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_example_elements_composite.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_example_elements_composite.yml
@@ -170,7 +170,7 @@ elements: |
       '#type': text_format
       '#title': 'Text format'
       '#description': '<b>Known Issues:</b><br /><a href="https://www.drupal.org/node/997826">Issue #997826: #states doesn''t work correctly with type text_format</a><br /><a href="https://www.drupal.org/node/2625128">Issue #2625128: Text format selection stays visible when using editor and a hidden webform state</a><br /><a href="https://www.drupal.org/node/1954968">Issue #1954968: Required CKEditor fields always fail HTML5 validation</a>'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -284,6 +284,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -334,3 +335,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_exporter_entity_reference.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_exporter_entity_reference.yml
index a7b0bdb4a9..b95d66c02a 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_exporter_entity_reference.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_exporter_entity_reference.yml
@@ -147,6 +147,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -197,3 +198,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_exporter_options.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_exporter_options.yml
index 7d40512255..2012df513b 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_exporter_options.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_exporter_options.yml
@@ -157,6 +157,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -207,3 +208,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_access_denied.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_access_denied.yml
index 1b24dddae7..cb6f252c6f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_access_denied.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_access_denied.yml
@@ -132,6 +132,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -181,3 +182,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_api.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_api.yml
index 5cc778afba..88aa731c62 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_api.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_api.yml
@@ -232,6 +232,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -282,3 +283,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_archived.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_archived.yml
index 7a8c9be8f8..b93e69fca8 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_archived.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_archived.yml
@@ -131,6 +131,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -181,3 +182,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_assets.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_assets.yml
index 500cd50f3d..947ef7fe5d 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_assets.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_assets.yml
@@ -144,6 +144,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -194,3 +195,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_autofill.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_autofill.yml
index b452239c33..307868e129 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_autofill.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_autofill.yml
@@ -136,6 +136,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -186,3 +187,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_autofocus.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_autofocus.yml
index 61c5c2f772..ebd67d3c8f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_autofocus.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_autofocus.yml
@@ -132,6 +132,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -182,3 +183,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_closed.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_closed.yml
index be051a5b34..996ca2f1af 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_closed.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_closed.yml
@@ -131,6 +131,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -181,3 +182,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_confidential.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_confidential.yml
index b6efb38c42..d6f52df03e 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_confidential.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_confidential.yml
@@ -132,6 +132,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -182,3 +183,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_details_toggle.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_details_toggle.yml
index c6bcfdf5f8..5d0af7947e 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_details_toggle.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_details_toggle.yml
@@ -139,6 +139,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -189,3 +190,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_autocomplete.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_autocomplete.yml
index 6f140e3be1..a642b2dcd9 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_autocomplete.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_autocomplete.yml
@@ -134,6 +134,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -184,3 +185,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_back.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_back.yml
index bba307076c..9a59ffc122 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_back.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_back.yml
@@ -459,6 +459,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -509,3 +510,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_inline_errors.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_inline_errors.yml
index c569052f4b..97a0383d8f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_inline_errors.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_inline_errors.yml
@@ -133,6 +133,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -183,3 +184,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_anonymous.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_anonymous.yml
index 2d9fc5987f..661fc1efa8 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_anonymous.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_anonymous.yml
@@ -136,6 +136,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -186,3 +187,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_authenticated.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_authenticated.yml
index 329a021f79..ec6048aeba 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_authenticated.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_authenticated.yml
@@ -136,6 +136,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -186,3 +187,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_multiple.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_multiple.yml
index ec1bb0ce83..d107c26361 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_multiple.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_multiple.yml
@@ -136,6 +136,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -186,3 +187,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_inline_errors.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_inline_errors.yml
index 52f91336dc..e3c8b3c02a 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_inline_errors.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_inline_errors.yml
@@ -240,6 +240,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -290,3 +291,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit.yml
index 13a061d69f..0e44d2ed8f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit.yml
@@ -152,6 +152,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -202,3 +203,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_total_unique.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_total_unique.yml
index a47316fc60..b1be12a96b 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_total_unique.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_total_unique.yml
@@ -132,6 +132,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -182,3 +183,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_user_unique.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_user_unique.yml
index 7ae959ebd7..4cbe583045 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_user_unique.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_user_unique.yml
@@ -132,6 +132,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -182,3 +183,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_wait.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_wait.yml
index 657685488f..f1c9ce45be 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_wait.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_wait.yml
@@ -141,6 +141,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -191,3 +192,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_100.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_100.yml
index 3cb4e262e1..0be20c564f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_100.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_100.yml
@@ -429,6 +429,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -479,3 +480,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_200.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_200.yml
index c58183fa62..d94dc396e7 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_200.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_200.yml
@@ -729,6 +729,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -779,3 +780,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_300.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_300.yml
index 3221f0cff5..112d68e54f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_300.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_300.yml
@@ -1029,6 +1029,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -1079,3 +1080,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_novalidate.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_novalidate.yml
index 6e1c3c1851..cd74ce573a 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_novalidate.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_novalidate.yml
@@ -136,6 +136,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -186,3 +187,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_opening.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_opening.yml
index 6f83ee42d0..697e9d6b02 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_opening.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_opening.yml
@@ -17,7 +17,7 @@ category: 'Test: Webform'
 elements: |
   description:
     '#markup': 'This message should not be displayed'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -131,6 +131,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -181,3 +182,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_prepopulate.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_prepopulate.yml
index bbc04baaf5..04709cc7ab 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_prepopulate.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_prepopulate.yml
@@ -38,6 +38,7 @@ elements: |
         type: _none
   prepopulate_name:
     '#markup': '<a href="?source_entity_type=user&source_entity_id=1&name=John+Smith&colors[]=red&colors[]=white&users[]=1">Prepopulate elements and source entity using query string parameter ?source_entity_type=user&source_entity_id=1&name=John+Smith&colors[]=red&colors[]=white&users[]=1</a>'
+  
 css: ''
 javascript: ''
 settings:
@@ -151,6 +152,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -201,3 +203,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_preview.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_preview.yml
index 59e75a790c..08ac6de031 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_preview.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_preview.yml
@@ -170,6 +170,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -220,3 +221,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_properties.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_properties.yml
index b7f5ae45f0..86ffdf8dbb 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_properties.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_properties.yml
@@ -144,6 +144,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -194,3 +195,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_remote_addr.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_remote_addr.yml
index edd6b39383..9f1c52239f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_remote_addr.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_remote_addr.yml
@@ -132,6 +132,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -182,3 +183,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_required.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_required.yml
index 1b74436f8c..3f88d7b248 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_required.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_required.yml
@@ -133,6 +133,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -183,3 +184,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_reset.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_reset.yml
index 1c22597f90..72076d2ee8 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_reset.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_reset.yml
@@ -133,6 +133,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -183,3 +184,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_results_disabled.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_results_disabled.yml
index 96da4c36db..88c2af129a 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_results_disabled.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_results_disabled.yml
@@ -131,6 +131,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -181,3 +182,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_back.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_back.yml
index d5588d254e..a78766c33c 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_back.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_back.yml
@@ -143,6 +143,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -193,3 +194,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_once.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_once.yml
index 441b1ac614..b753d0dc25 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_once.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_once.yml
@@ -140,6 +140,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -190,3 +191,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_text.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_text.yml
index f4fd31c789..000b56effb 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_text.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_text.yml
@@ -133,6 +133,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -183,3 +184,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_template.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_template.yml
index 1dd4b955c5..42c4dbcf9d 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_template.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_template.yml
@@ -131,6 +131,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -181,3 +182,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved.yml
index 3c3c4bf403..abcff8c6bd 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved.yml
@@ -137,6 +137,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -187,3 +188,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved_wizard.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved_wizard.yml
index 3bb13b9802..19e66c3a08 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved_wizard.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved_wizard.yml
@@ -141,6 +141,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -191,3 +192,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_validate.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_validate.yml
index 02d6d77a84..4f53db218c 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_validate.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_validate.yml
@@ -132,6 +132,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -182,3 +183,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_access.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_access.yml
index fc3bc288fe..1e32bc1e2c 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_access.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_access.yml
@@ -170,6 +170,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -224,3 +225,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_advanced.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_advanced.yml
index fa126f054a..d4382750b3 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_advanced.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_advanced.yml
@@ -174,6 +174,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -224,3 +225,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_basic.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_basic.yml
index 8e7a179333..465894474d 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_basic.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_basic.yml
@@ -143,6 +143,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -193,3 +194,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_conditional.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_conditional.yml
index f446e98d84..8805f128bf 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_conditional.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_conditional.yml
@@ -212,6 +212,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -262,3 +263,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_custom.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_custom.yml
index 5d286f8793..e5c607932f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_custom.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_custom.yml
@@ -175,6 +175,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -225,3 +226,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_links.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_links.yml
index aaf0f0a6aa..766262bcc0 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_links.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_links.yml
@@ -143,6 +143,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -193,3 +194,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_100.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_100.yml
index 3e2e6ce391..abfdafc9f2 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_100.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_100.yml
@@ -459,6 +459,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -509,3 +510,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_200.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_200.yml
index 6a8a77880a..391c3fd499 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_200.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_200.yml
@@ -789,6 +789,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -839,3 +840,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_300.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_300.yml
index adca85226f..66de28b231 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_300.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_300.yml
@@ -1119,6 +1119,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -1169,3 +1170,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_validate.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_validate.yml
index 63c704b8ae..de89788e48 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_validate.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_validate.yml
@@ -172,6 +172,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -230,3 +231,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_validate_comp.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_validate_comp.yml
index 11ed4e8200..743cb0bba7 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_validate_comp.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_validate_comp.yml
@@ -220,6 +220,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -278,3 +279,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_action.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_action.yml
index 64ccfada97..51b5a80454 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_action.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_action.yml
@@ -161,6 +161,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -329,3 +330,4 @@ handlers:
       message: 'Submission has been unlocked.'
       message_type: status
       debug: true
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email.yml
index 5ef7ce0573..fb45ed8451 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email.yml
@@ -40,7 +40,7 @@ elements: |
     '#type': textarea
     '#required': true
     '#default_value': '{message}'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -154,6 +154,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -240,3 +241,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_advanced.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_advanced.yml
index 672ae482a7..dae3b67462 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_advanced.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_advanced.yml
@@ -55,7 +55,7 @@ elements: |
     '#title': Notes
     '#private': true
     '#default_value': 'These notes are private.'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -169,6 +169,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -246,7 +247,7 @@ handlers:
         [webform_submission:values]
         <hr />
         <p style="color:yellow"><em>Custom styled HTML markup</em></p>
-
+        
       excluded_elements: {  }
       ignore_access: true
       exclude_empty: true
@@ -263,3 +264,4 @@ handlers:
       return_path: return_path@example.com
       sender_mail: sender_mail@example.com
       sender_name: sender_name
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_mapping.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_mapping.yml
index abdc2d2da3..cf507a48dd 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_mapping.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_mapping.yml
@@ -30,7 +30,7 @@ elements: |
     '#title': radios_other
     '#options': gender
     '#description': 'Check and enter ''Other'' to trigger an email.'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -144,6 +144,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -386,3 +387,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_roles.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_roles.yml
index f29694dde9..366251dcec 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_roles.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_roles.yml
@@ -22,7 +22,7 @@ elements: |
       authenticated: 'Authenticated (authenticated)'
       administrator: 'Administrator (administrator)'
       other: Other
-
+  
 css: ''
 javascript: ''
 settings:
@@ -136,6 +136,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -228,3 +229,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_states.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_states.yml
index 502b45a0ce..f664d37daa 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_states.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_states.yml
@@ -17,7 +17,7 @@ category: 'Test: Handler'
 elements: |
   message:
     '#markup': 'Click ''Save Draft'' and ''Submit'' to send emails triggered by submissions  state.'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -131,6 +131,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -433,3 +434,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_twig.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_twig.yml
index 666cb978b2..0d16257dd6 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_twig.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_twig.yml
@@ -40,7 +40,7 @@ elements: |
     '#type': textarea
     '#required': true
     '#default_value': '{message}'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -154,6 +154,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -227,7 +228,7 @@ handlers:
       body: |
         <p>Submitted values are:</p>
         {{ webform_token('[webform_submission:values]', webform_submission) }}
-
+        
       excluded_elements: {  }
       ignore_access: false
       exclude_empty: true
@@ -243,3 +244,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_settings.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_settings.yml
index bef4fd6625..602c4dffec 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_settings.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_settings.yml
@@ -174,6 +174,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -277,3 +278,4 @@ handlers:
       debug: '1'
       draft_saved_message: '[webform_submission:values:draft_saved_message]'
       draft_loaded_message: '[webform_submission:values:draft_loaded_message]'
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_libraries_optional.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_libraries_optional.yml
index fac5679a63..2262992ff0 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_libraries_optional.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_libraries_optional.yml
@@ -84,7 +84,7 @@ elements: |
     signature:
       '#type': webform_signature
       '#title': Signature
-
+  
 css: ''
 javascript: ''
 settings:
@@ -198,6 +198,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -248,3 +249,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_rendering.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_rendering.yml
index 8a2e03a15c..5acc8e59ab 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_rendering.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_rendering.yml
@@ -49,7 +49,7 @@ elements: |
     '#default_value':
       value: '<p><em>{default_value}</em></p>'
       format: basic_html
-
+  
 css: ''
 javascript: ''
 settings:
@@ -163,6 +163,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: true
 access:
@@ -285,3 +286,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states.yml
index 6632eaee02..b61408a499 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states.yml
@@ -2553,7 +2553,7 @@ elements: |
         disabled:
           ':input[name="disabled_trigger"]':
             checked: true
-
+  
 css: ''
 javascript: ''
 settings:
@@ -2667,6 +2667,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -2717,3 +2718,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_autocomplete.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_autocomplete.yml
index ac40b8f961..0611f8e95f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_autocomplete.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_autocomplete.yml
@@ -273,6 +273,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -323,3 +324,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_crosspage.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_crosspage.yml
index 161e02c0af..1e0f5d4c7f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_crosspage.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_crosspage.yml
@@ -159,6 +159,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -209,3 +210,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_disabled.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_disabled.yml
index a14993977c..8ada98d889 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_disabled.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_disabled.yml
@@ -59,6 +59,7 @@ elements: |
       disabled:
         ':input[name="disabled"]':
           checked: true
+  
 css: ''
 javascript: ''
 settings:
@@ -172,6 +173,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_clear.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_clear.yml
index 12a8cad4d3..5083518a0a 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_clear.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_clear.yml
@@ -216,6 +216,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -274,3 +275,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_comp.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_comp.yml
index 8b7ad42e96..7f6fd5c003 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_comp.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_comp.yml
@@ -190,6 +190,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -240,3 +241,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_containers.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_containers.yml
index 7188b4cd18..3358b287ec 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_containers.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_containers.yml
@@ -187,6 +187,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -237,3 +238,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_custom.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_custom.yml
index c864958f26..66ead27d86 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_custom.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_custom.yml
@@ -105,6 +105,7 @@ elements: |
       visible-slide:
         ':input[name="trigger_visible_slide"]':
           checked: true
+  
 css: ''
 javascript: ''
 settings:
@@ -218,6 +219,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_hidden.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_hidden.yml
index 5c0a669f81..538c88419e 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_hidden.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_hidden.yml
@@ -252,6 +252,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -310,3 +311,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_likert.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_likert.yml
index 93fbbfbc91..e0de159a69 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_likert.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_likert.yml
@@ -147,6 +147,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -197,3 +198,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_multiple.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_multiple.yml
index 9a289e80f3..628dcb0770 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_multiple.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_multiple.yml
@@ -141,6 +141,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -191,3 +192,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_nested.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_nested.yml
index c43984fdfa..783370399f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_nested.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_nested.yml
@@ -172,6 +172,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -222,3 +223,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_preview.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_preview.yml
index ddb64e0fe8..d304483686 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_preview.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_preview.yml
@@ -166,6 +166,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -216,3 +217,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_required.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_required.yml
index c1a6890b24..c787555757 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_required.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_required.yml
@@ -561,6 +561,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -611,3 +612,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_save.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_save.yml
index 4314a4b46b..9cbbffe99d 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_save.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_save.yml
@@ -184,6 +184,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -242,3 +243,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_wizard.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_wizard.yml
index ee6755208b..6a069da3d7 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_wizard.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_wizard.yml
@@ -334,6 +334,7 @@ settings:
   purge_days: null
   results_disabled: true
   results_disabled_ignore: true
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -392,3 +393,4 @@ handlers:
     conditions: {  }
     weight: 1
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_triggers.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_triggers.yml
index 7d57047e83..cf02119e3c 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_triggers.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_triggers.yml
@@ -244,6 +244,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -294,3 +295,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_label.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_label.yml
index 1db188dbcf..ccd10b07ae 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_label.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_label.yml
@@ -133,6 +133,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -183,3 +184,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_log.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_log.yml
index 77b24e1476..a504fc8b8e 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_log.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_log.yml
@@ -132,6 +132,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -182,3 +183,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_views.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_views.yml
index 292589d95d..1bace4a296 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_views.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_views.yml
@@ -162,6 +162,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -212,3 +213,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token.yml
index c7f318bbd7..09a9db5f90 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token.yml
@@ -34,7 +34,7 @@ elements: |
       Close long: [webform:close:long]
       Element title: [webform:element:webform_tokens:title]
       Element description: [webform:element:webform_tokens:description]
-
+  
   webform_submission_tokens:
     '#type': webform_codemirror
     '#mode': text
@@ -67,7 +67,7 @@ elements: |
       URL: [webform_submission:url]
       URL Edit Webform: [webform_submission:url:edit-form]
       UUID: [webform_submission:uuid]
-
+  
   webform_submission_source_entity_tokens:
     '#type': webform_codemirror
     '#mode': text
@@ -96,7 +96,7 @@ elements: |
       Summary: [webform_submission:source-entity:summary]
       Title: [webform_submission:source-entity:title]
       URL: [webform_submission:source-entity:url]
-
+  
   webform_submission_node_tokens:
     '#type': webform_codemirror
     '#mode': text
@@ -125,7 +125,7 @@ elements: |
       Summary: [webform_submission:node:summary]
       Title: [webform_submission:node:title]
       URL: [webform_submission:node:url]
-
+  
 css: ''
 javascript: ''
 settings:
@@ -239,6 +239,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: true
 access:
@@ -325,3 +326,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token_submission_value.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token_submission_value.yml
index c76c13978f..49a5e28963 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token_submission_value.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token_submission_value.yml
@@ -126,6 +126,9 @@ elements: |
       '#type': textfield
       '#title': last_name
       '#default_value': Smith
+  webform_markup:
+    '#type': webform_markup
+    '#markup': '<strong>This is some basic HTML.</strong>'
   url:
     '#type': url
     '#title': url
@@ -138,7 +141,7 @@ elements: |
     '#type': textfield
     '#title': script
     '#default_value': '<script>alert(''hi'');</script>'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -236,7 +239,7 @@ settings:
     <tr><th width="50%">webform:element:not_element:description</th><td width="50%">[webform:element:not_element:description]</td></tr>
     <tr><th width="50%">webform:element:email:not_property</th><td width="50%">[webform:element:email:not_property]</td></tr>
     </table>
-    
+
     <h3>checkboxes</h3>
     <table class="table">
     <tr><th width="50%">webform:element:checkboxes</th><td width="50%">[webform_submission:values:checkboxes]</td></tr>
@@ -244,7 +247,7 @@ settings:
     <tr><th width="50%">webform:element:checkboxes:selected:two</th><td width="50%">[webform_submission:values:checkboxes:selected:two]</td></tr>
     <tr><th width="50%">webform:element:checkboxes:selected:three</th><td width="50%">[webform_submission:values:checkboxes:selected:three]</td></tr>
     </table>
-    
+
     <h3>emails</h3>
     <table class="table">
     <tr><th width="50%">webform_submission:values:email</th><td width="50%">[webform_submission:values:email]</td></tr>
@@ -259,7 +262,7 @@ settings:
     <tr><th width="50%">webform_submission:values:emails:2:html</th><td width="50%">[webform_submission:values:emails:2:html]</td></tr>
     <tr><th width="50%">webform_submission:values:emails:99:html</th><td width="50%">[webform_submission:values:emails:99]</td></tr>
     </table>
-    
+
     <h3>users</h3>
     <table class="table">
     <tr><th width="50%">webform_submission:values:user</th><td width="50%">[webform_submission:values:user]</td></tr>
@@ -268,13 +271,13 @@ settings:
     <tr><th width="50%">webform_submission:values:users:0:entity:account-name</th><td width="50%">[webform_submission:values:users:0:entity:account-name]</td></tr>
     <tr><th width="50%">webform_submission:values:users:99:entity:account-name</th><td width="50%">[webform_submission:values:users:99:entity:account-name]</td></tr>
     </table>
-    
+
     <h3>current-user</h3>
     <table class="table">
     <tr><th width="50%">current-user:display-name</th><td width="50%">[current-user:display-name]</td></tr>
     <tr><th width="50%">current-user:missing</th><td width="50%">[current-user:missing]</td></tr>
     </table>
-    
+
     <h3>terms</h3>
     <table class="table">
     <tr><th width="50%">webform_submission:values:term</th><td width="50%">[webform_submission:values:term]</td></tr>
@@ -283,7 +286,7 @@ settings:
     <tr><th width="50%">webform_submission:values:terms:entity:name</th><td width="50%">[webform_submission:values:terms:entity:name]</td></tr>
     <tr><th width="50%">webform_submission:values:terms:1:entity:name</th><td width="50%">[webform_submission:values:terms:1:entity:name]</td></tr>
     </table>
-    
+
     <h3>names</h3>
     <table class="table">
     <tr><th width="50%">webform_submission:values:name</th><td width="50%">[webform_submission:values:name]</td></tr>
@@ -292,7 +295,7 @@ settings:
     <tr><th width="50%">webform_submission:values:names:1</th><td width="50%">[webform_submission:values:names:1]</td></tr>
     <tr><th width="50%">webform_submission:values:names:99</th><td width="50%">[webform_submission:values:names:99]</td></tr>
     </table>
-    
+
     <h3>contacts</h3>
     <table class="table">
     <tr><th width="50%">webform_submission:values:contact</th><td width="50%">[webform_submission:values:contact]</td></tr>
@@ -304,7 +307,7 @@ settings:
     <tr><th width="50%">webform_submission:values:contacts:0:email:html</th><td width="50%">[webform_submission:values:contacts:0:email:html]</td></tr>
     <tr><th width="50%">webform_submission:values:contacts:1:email:raw:html</th><td width="50%">[webform_submission:values:contacts:1:email:raw:html]</td></tr>
     </table>
-    
+
     <h3>container</h3>
     <table class="table">
     <tr><th width="50%">webform_submission:values:fieldset</th><td width="50%"><pre>[webform_submission:values:fieldset]</pre></td></tr>
@@ -313,7 +316,7 @@ settings:
     <tr><th width="50%">webform_submission:values:fieldset:details:html</th><td width="50%">[webform_submission:values:fieldset:details:html]</td></tr>
     <tr><th width="50%">webform_submission:values:fieldset:fieldset:html</th><td width="50%">[webform_submission:values:fieldset:fieldset:html]</td></tr>
     </table>
-    
+
     <h3>submission limits</h3>
     <table class="table">
     <tr><th width="50%">webform_submission:limit:webform</th><td width="50%">[webform_submission:limit:webform]</td></tr>
@@ -325,7 +328,13 @@ settings:
     <tr><th width="50%">webform_submission:limit:user:source_entity</th><td width="50%">[webform_submission:limit:user:source_entity]</td></tr>
     <tr><th width="50%">webform_submission:total:user:source_entity</th><td width="50%">[webform_submission:total:user:source_entity]</td></tr>
     </table>
-    
+
+    <h3>markup</h3>
+    <table class="table">
+    <tr><th width="50%">webform_submission:values:webform_markup</th><td width="50%">[webform_submission:values:webform_markup]</td></tr>
+    <tr><th width="50%">webform_submission:values:webform_markup:html</th><td width="50%">[webform_submission:values:webform_markup:html]</td></tr>
+    </table>
+
     <h3>clear</h3>
     <table class="table">
     <tr><th width="50%">webform_submission:values:missing</th><td width="50%">[webform_submission:values:missing]</td></tr>
@@ -333,13 +342,13 @@ settings:
     <tr><th width="50%">webform:random:missing</th><td width="50%">[webform:random:missing]</td></tr>
     <tr><th width="50%">webform:random:missing:clear</th><td width="50%">[webform:random:missing:clear]</td></tr>
     </table>
-    
+
     <h3>urlencode</h3>
     <table class="table">
     <tr><th width="50%">webform_submission:values:url</th><td width="50%">[webform_submission:values:url]</td></tr>
     <tr><th width="50%">webform_submission:values:url:urlencode</th><td width="50%">[webform_submission:values:url:urlencode]</td></tr>
     </table>
-    
+
     <h3>htmldecode</h3>
     <table class="table">
     <tr><th width="50%">webform_submission:values:markup</th><td width="50%">[webform_submission:values:markup]</td></tr>
@@ -348,7 +357,7 @@ settings:
     <tr><th width="50%">webform_submission:values:script</th><td width="50%">[webform_submission:values:script]</td></tr>
     <tr><th width="50%">webform_submission:values:script:htmldecode</th><td width="50%">[webform_submission:values:script:htmldecode]</td></tr>
     </table>
-    
+
   confirmation_url: ''
   confirmation_attributes: {  }
   confirmation_back: true
@@ -373,6 +382,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: true
 access:
@@ -423,3 +433,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token_view_update.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token_view_update.yml
index 9c4b18952d..1d6ded0ca7 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token_view_update.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token_view_update.yml
@@ -18,7 +18,7 @@ elements: |
   textfield:
     '#type': textfield
     '#title': textfield
-
+  
 css: ''
 javascript: ''
 settings:
@@ -110,7 +110,7 @@ settings:
   confirmation_message: |
     <p>You can view your submission via <a href="[webform_submission:view-url]">[webform_submission:view-url:relative]</a></p>
     <p>You can update your submission via <a href="[webform_submission:update-url]">[webform_submission:update-url:relative]</a></p>
-
+    
   confirmation_url: ''
   confirmation_attributes: {  }
   confirmation_back: true
@@ -135,6 +135,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: true
   token_update: true
 access:
@@ -208,7 +209,7 @@ handlers:
       body: |
         <a href="[webform_submission:view-url]">[webform_submission:view-url]</a><br/>
         <a href="[webform_submission:update-url]">[webform_submission:update-url]</a>
-
+        
       excluded_elements: {  }
       ignore_access: false
       exclude_empty: true
@@ -224,3 +225,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_multiple.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_multiple.yml
index 31ffeae735..ab13bdd906 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_multiple.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_multiple.yml
@@ -33,6 +33,7 @@ elements: |
     '#wrapper_attributes':
       style: 'display: inline-block; margin: 0; padding: 0 20px; font-size: 100px; '
     '#markup': '{0}'
+  
 css: ''
 javascript: ''
 settings:
@@ -146,6 +147,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -218,7 +220,7 @@ variants:
       elements: |
         letter_markup:
           '#markup': '[A]'
-
+        
       handlers: {  }
       debug: false
   b:
@@ -234,7 +236,7 @@ variants:
       elements: |
         letter_markup:
           '#markup': '[B]'
-
+        
       handlers: {  }
       debug: false
   1:
@@ -250,7 +252,7 @@ variants:
       elements: |
         number_markup:
           '#markup': '[1]'
-
+        
       handlers: {  }
       debug: false
   2:
@@ -266,7 +268,7 @@ variants:
       elements: |
         number_markup:
           '#markup': '[2]'
-
+        
       handlers: {  }
       debug: false
   3:
@@ -282,6 +284,6 @@ variants:
       elements: |
         number_markup:
           '#markup': '[3]'
-
+        
       handlers: {  }
       debug: false
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_override.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_override.yml
index dac549db17..70f5497ea9 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_override.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_override.yml
@@ -23,6 +23,7 @@ elements: |
   textfield:
     '#type': textfield
     '#title': textfield
+  
 css: ''
 javascript: ''
 settings:
@@ -136,6 +137,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -222,7 +224,7 @@ variants:
       elements: |
         textfield:
           '#placeholder': 'This is a placeholder'
-
+        
       handlers: {  }
       debug: true
   handlers:
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_randomize.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_randomize.yml
index dedc10842b..e65e1cf4cf 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_randomize.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_randomize.yml
@@ -25,6 +25,7 @@ elements: |
     '#attributes':
       style: 'display: inline-block; margin: 0; padding: 0 20px; font-size: 100px;'
     '#markup': '{X}'
+  
 css: ''
 javascript: ''
 settings:
@@ -138,6 +139,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -210,7 +212,7 @@ variants:
       elements: |
         letter_markup:
           '#markup': '[A]'
-
+        
       handlers: {  }
       debug: false
   b:
@@ -226,6 +228,6 @@ variants:
       elements: |
         letter_markup:
           '#markup': '[B]'
-
+        
       handlers: {  }
       debug: false
diff --git a/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_element_description_tooltip.inc b/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_element_description_tooltip.inc
index 64912d4d1d..3b4146e2a7 100644
--- a/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_element_description_tooltip.inc
+++ b/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_element_description_tooltip.inc
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Generate test elements with with description tooltips.
+ * Generate test elements with description tooltips.
  */
 
 /**
diff --git a/web/modules/webform/tests/modules/webform_test/webform_test.info.yml b/web/modules/webform/tests/modules/webform_test/webform_test.info.yml
index 20e7989cb7..1e1e340c96 100644
--- a/web/modules/webform/tests/modules/webform_test/webform_test.info.yml
+++ b/web/modules/webform/tests/modules/webform_test/webform_test.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test/webform_test.module b/web/modules/webform/tests/modules/webform_test/webform_test.module
index a475549d0c..6f07b6e8e4 100644
--- a/web/modules/webform/tests/modules/webform_test/webform_test.module
+++ b/web/modules/webform/tests/modules/webform_test/webform_test.module
@@ -9,6 +9,28 @@
 use Drupal\Core\Url;
 use Drupal\webform\Utility\WebformElementHelper;
 
+/**
+ * Test element callback that should be ignored.
+ *
+ * @param array $element
+ *   An element.
+ *
+ * @return array
+ *   An element.
+ */
+function webform_test_ignored_element_callback($arg = NULL) {
+  // Display error message when this callback is executed.
+  if (is_array($arg) && isset($arg['#title'])) {
+    $message = t('Callback not ignored for @title', ['@title' => $arg['#title']]);
+    \Drupal::messenger()->addError($message);
+    return $arg;
+  }
+  else {
+    $message = t('Callback not ignored');
+    \Drupal::messenger()->addError($message);
+  }
+}
+
 /******************************************************************************/
 // Generate elements.
 /******************************************************************************/
diff --git a/web/modules/webform/tests/modules/webform_test_ajax/webform_test_ajax.info.yml b/web/modules/webform/tests/modules/webform_test_ajax/webform_test_ajax.info.yml
index e1bb00d985..e9cad6fee0 100644
--- a/web/modules/webform/tests/modules/webform_test_ajax/webform_test_ajax.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_ajax/webform_test_ajax.info.yml
@@ -7,7 +7,7 @@ dependencies:
   - 'drupal:block'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_alter_hooks/webform_test_alter_hooks.info.yml b/web/modules/webform/tests/modules/webform_test_alter_hooks/webform_test_alter_hooks.info.yml
index 586bbfd486..4e78f2d63b 100644
--- a/web/modules/webform/tests/modules/webform_test_alter_hooks/webform_test_alter_hooks.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_alter_hooks/webform_test_alter_hooks.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_block_context/webform_test_block_context.info.yml b/web/modules/webform/tests/modules/webform_test_block_context/webform_test_block_context.info.yml
index 957993bd5a..420fb6ac2e 100644
--- a/web/modules/webform/tests/modules/webform_test_block_context/webform_test_block_context.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_block_context/webform_test_block_context.info.yml
@@ -7,7 +7,7 @@ dependencies:
   - 'drupal:block'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_block_custom/webform_test_block_custom.info.yml b/web/modules/webform/tests/modules/webform_test_block_custom/webform_test_block_custom.info.yml
index a626673854..235313f4c2 100644
--- a/web/modules/webform/tests/modules/webform_test_block_custom/webform_test_block_custom.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_block_custom/webform_test_block_custom.info.yml
@@ -8,7 +8,7 @@ dependencies:
   - 'drupal:block_content'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_block_submission_limit/webform_test_block_submission_limit.info.yml b/web/modules/webform/tests/modules/webform_test_block_submission_limit/webform_test_block_submission_limit.info.yml
index 909729e39f..85869b7e2d 100644
--- a/web/modules/webform/tests/modules/webform_test_block_submission_limit/webform_test_block_submission_limit.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_block_submission_limit/webform_test_block_submission_limit.info.yml
@@ -7,7 +7,7 @@ dependencies:
   - 'drupal:block'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_config_performance/webform_test_config_performance.info.yml b/web/modules/webform/tests/modules/webform_test_config_performance/webform_test_config_performance.info.yml
index ed68bba6c5..6f2f87a386 100644
--- a/web/modules/webform/tests/modules/webform_test_config_performance/webform_test_config_performance.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_config_performance/webform_test_config_performance.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_comp_file_plugin.yml b/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_comp_file_plugin.yml
index 6b01bdf561..b11b36c12b 100644
--- a/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_comp_file_plugin.yml
+++ b/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_comp_file_plugin.yml
@@ -141,6 +141,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -199,3 +200,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_composite_plugin.yml b/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_composite_plugin.yml
index 96fb4ac3dc..cddb9824df 100644
--- a/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_composite_plugin.yml
+++ b/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_composite_plugin.yml
@@ -141,6 +141,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -199,3 +200,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_plugin.yml b/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_plugin.yml
index a80e0bb47e..89ce23ce38 100644
--- a/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_plugin.yml
+++ b/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_plugin.yml
@@ -137,6 +137,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -187,3 +188,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test_element/webform_test_element.info.yml b/web/modules/webform/tests/modules/webform_test_element/webform_test_element.info.yml
index 27fad13865..186041b32a 100644
--- a/web/modules/webform/tests/modules/webform_test_element/webform_test_element.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_element/webform_test_element.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_element_input_masks/webform_test_element_input_masks.info.yml b/web/modules/webform/tests/modules/webform_test_element_input_masks/webform_test_element_input_masks.info.yml
index c01ea3e0bf..22c34a77f7 100644
--- a/web/modules/webform/tests/modules/webform_test_element_input_masks/webform_test_element_input_masks.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_element_input_masks/webform_test_element_input_masks.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_entity_reference/config/install/webform.webform.test_element_entity_reference_vs.yml b/web/modules/webform/tests/modules/webform_test_entity_reference/config/install/webform.webform.test_element_entity_reference_vs.yml
index fe396ab8ee..ff8db53ad5 100644
--- a/web/modules/webform/tests/modules/webform_test_entity_reference/config/install/webform.webform.test_element_entity_reference_vs.yml
+++ b/web/modules/webform/tests/modules/webform_test_entity_reference/config/install/webform.webform.test_element_entity_reference_vs.yml
@@ -247,6 +247,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -305,3 +306,4 @@ handlers:
     conditions: {  }
     weight: 0
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test_entity_reference/webform_test_entity_reference_views.info.yml b/web/modules/webform/tests/modules/webform_test_entity_reference/webform_test_entity_reference_views.info.yml
index 0f0d88b39b..5a5b799ace 100644
--- a/web/modules/webform/tests/modules/webform_test_entity_reference/webform_test_entity_reference_views.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_entity_reference/webform_test_entity_reference_views.info.yml
@@ -9,7 +9,7 @@ dependencies:
   - 'drupal:views'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_exporter/webform_test_exporter.info.yml b/web/modules/webform/tests/modules/webform_test_exporter/webform_test_exporter.info.yml
index 5467aed69f..1da2e17345 100644
--- a/web/modules/webform/tests/modules/webform_test_exporter/webform_test_exporter.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_exporter/webform_test_exporter.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_conditions.yml b/web/modules/webform/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_conditions.yml
index c7107f8d4e..d4570f068e 100644
--- a/web/modules/webform/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_conditions.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_conditions.yml
@@ -137,6 +137,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -211,3 +212,4 @@ handlers:
     weight: 1
     settings:
       message: 'Test B'
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_test.yml b/web/modules/webform/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_test.yml
index 7fda6e2e9f..5b2f2d6e3c 100644
--- a/web/modules/webform/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_test.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_test.yml
@@ -21,7 +21,7 @@ elements: |
     '#type': textfield
     '#title': 'Empty element'
     '#description': 'Entering any value will throw an error'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -135,6 +135,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -202,3 +203,4 @@ handlers:
     conditions: {  }
     weight: 2
     settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test_handler/webform_test_handler.info.yml b/web/modules/webform/tests/modules/webform_test_handler/webform_test_handler.info.yml
index a288f6cd2c..a406830d8a 100644
--- a/web/modules/webform/tests/modules/webform_test_handler/webform_test_handler.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler/webform_test_handler.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_handler_invoke_alter/webform_test_handler_invoke_alter.info.yml b/web/modules/webform/tests/modules/webform_test_handler_invoke_alter/webform_test_handler_invoke_alter.info.yml
index 2ad1d324dc..d335c4b0a3 100644
--- a/web/modules/webform/tests/modules/webform_test_handler_invoke_alter/webform_test_handler_invoke_alter.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler_invoke_alter/webform_test_handler_invoke_alter.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_get.yml b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_get.yml
index c00bf40249..9f056e3657 100644
--- a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_get.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_get.yml
@@ -37,7 +37,7 @@ elements: |
     '#title': 'Confirmation number'
     '#type': value
     '#value': '[webform:handler:remote_post:completed:confirmation_number]'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -128,7 +128,7 @@ settings:
   confirmation_title: ''
   confirmation_message: |
     <p>Your confirmation number is [webform_submission:values:confirmation_number].</p>
-
+    
   confirmation_url: ''
   confirmation_attributes: {  }
   confirmation_back: true
@@ -153,6 +153,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -236,37 +237,38 @@ handlers:
         confirmation_number: confirmation_number
       custom_data: |
         custom_data: true
-
+        
       custom_options: |
         headers:
           custom_header: 'true'
-
+        
       cast: false
       debug: true
       completed_url: 'http://webform-test-handler-remote-post/completed'
       completed_custom_data: |
         custom_completed: true
-
+        
       updated_url: 'http://webform-test-handler-remote-post/updated'
       updated_custom_data: |
         custom_updated: true
-
+        
       deleted_url: 'http://webform-test-handler-remote-post/deleted'
       deleted_custom_data: |
         custom_deleted: true
-
+        
       draft_created_url: 'http://webform-test-handler-remote-post/draft_created'
       draft_created_custom_data: |
         custom_draft_created: true
-
+        
       draft_updated_url: 'http://webform-test-handler-remote-post/draft_updated'
       draft_updated_custom_data: |
         custom_draft_updated: true
-
+        
       converted_url: 'http://webform-test-handler-remote-post/converted'
       converted_custom_data: |
         custom_converted: true
-
+        
       message: ''
       messages: {  }
       error_url: ''
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post.yml b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post.yml
index f66ae7fd17..c7a8abc4e7 100644
--- a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post.yml
@@ -38,7 +38,7 @@ elements: |
     '#title': 'Confirmation number'
     '#type': value
     '#value': '[webform:handler:remote_post:completed:confirmation_number]'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -129,7 +129,7 @@ settings:
   confirmation_title: ''
   confirmation_message: |
     <p>Your confirmation number is [webform_submission:values:confirmation_number].</p>
-
+    
   confirmation_url: ''
   confirmation_attributes: {  }
   confirmation_back: true
@@ -154,6 +154,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -237,38 +238,38 @@ handlers:
         confirmation_number: confirmation_number
       custom_data: |
         custom_data: true
-
+        
       custom_options: |
         headers:
           'Accept-Language': '[webform_submission:langcode]'
           custom_header: 'true'
-
+        
       cast: false
       debug: true
       completed_url: 'http://webform-test-handler-remote-post/completed'
       completed_custom_data: |
         custom_completed: true
-
+        
       updated_url: 'http://webform-test-handler-remote-post/updated'
       updated_custom_data: |
         custom_updated: true
-
+        
       deleted_url: 'http://webform-test-handler-remote-post/deleted'
       deleted_custom_data: |
         custom_deleted: true
-
+        
       draft_created_url: 'http://webform-test-handler-remote-post/draft_created'
       draft_created_custom_data: |
         custom_draft_created: true
-
+        
       draft_updated_url: 'http://webform-test-handler-remote-post/draft_updated'
       draft_updated_custom_data: |
         custom_draft_updated: true
-
+        
       converted_url: 'http://webform-test-handler-remote-post/converted'
       converted_custom_data: |
         custom_converted: true
-
+        
       message: ''
       messages:
         - code: 401
@@ -276,3 +277,4 @@ handlers:
         - code: 404
           message: 'This is a custom 404 not found message.'
       error_url: ''
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post_cast.yml b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post_cast.yml
index 3f85dd1b90..34b6db3dde 100644
--- a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post_cast.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post_cast.yml
@@ -38,6 +38,7 @@ elements: |
       number:
         '#type': number
         '#title': number
+  
 css: ''
 javascript: ''
 settings:
@@ -130,7 +131,7 @@ settings:
   confirmation_title: ''
   confirmation_message: |
     <p>Your confirmation number is [webform_submission:values:confirmation_number].</p>
-
+    
   confirmation_url: ''
   confirmation_attributes: {  }
   confirmation_back: true
@@ -155,6 +156,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
diff --git a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post_file.yml b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post_file.yml
index 6cd9b01aaa..b289ee6c0b 100644
--- a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post_file.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post_file.yml
@@ -26,7 +26,7 @@ elements: |
     '#required': true
     '#multiple': true
     '#file_extensions': txt
-
+  
 css: ''
 javascript: ''
 settings:
@@ -117,7 +117,7 @@ settings:
   confirmation_title: ''
   confirmation_message: |
     <p>Your confirmation number is [webform_submission:values:confirmation_number].</p>
-
+    
   confirmation_url: ''
   confirmation_attributes: {  }
   confirmation_back: true
@@ -142,6 +142,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -242,3 +243,4 @@ handlers:
       message: ''
       messages: {  }
       error_url: ''
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_put.yml b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_put.yml
index 33a5465c05..9db3992afd 100644
--- a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_put.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_put.yml
@@ -37,7 +37,7 @@ elements: |
     '#title': 'Confirmation number'
     '#type': value
     '#value': '[webform:handler:remote_post:completed:confirmation_number]'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -128,7 +128,7 @@ settings:
   confirmation_title: ''
   confirmation_message: |
     <p>Your confirmation number is [webform_submission:values:confirmation_number].</p>
-
+    
   confirmation_url: ''
   confirmation_attributes: {  }
   confirmation_back: true
@@ -153,6 +153,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -236,37 +237,38 @@ handlers:
         confirmation_number: confirmation_number
       custom_data: |
         custom_data: true
-
+        
       custom_options: |
         headers:
           custom_header: 'true'
-
+        
       cast: false
       debug: true
       completed_url: 'http://webform-test-handler-remote-post/completed'
       completed_custom_data: |
         custom_completed: true
-
+        
       updated_url: 'http://webform-test-handler-remote-post/updated'
       updated_custom_data: |
         custom_updated: true
-
+        
       deleted_url: 'http://webform-test-handler-remote-post/deleted'
       deleted_custom_data: |
         custom_deleted: true
-
+        
       draft_created_url: 'http://webform-test-handler-remote-post/draft_created'
       draft_created_custom_data: |
         custom_draft_created: true
-
+        
       draft_updated_url: 'http://webform-test-handler-remote-post/draft_updated'
       draft_updated_custom_data: |
         custom_draft_updated: true
-
+        
       converted_url: 'http://webform-test-handler-remote-post/converted'
       converted_custom_data: |
         custom_converted: true
-
+        
       message: ''
       messages: {  }
       error_url: ''
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test_handler_remote_post/webform_test_handler_remote_post.info.yml b/web/modules/webform/tests/modules/webform_test_handler_remote_post/webform_test_handler_remote_post.info.yml
index e9f5ca3f3d..93e37baa60 100644
--- a/web/modules/webform/tests/modules/webform_test_handler_remote_post/webform_test_handler_remote_post.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler_remote_post/webform_test_handler_remote_post.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_markup/webform_test_markup.info.yml b/web/modules/webform/tests/modules/webform_test_markup/webform_test_markup.info.yml
index b7e2a078eb..2a5ea1f554 100644
--- a/web/modules/webform/tests/modules/webform_test_markup/webform_test_markup.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_markup/webform_test_markup.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_message_custom/webform_test_message_custom.info.yml b/web/modules/webform/tests/modules/webform_test_message_custom/webform_test_message_custom.info.yml
index 49006853ec..5256d7378e 100644
--- a/web/modules/webform/tests/modules/webform_test_message_custom/webform_test_message_custom.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_message_custom/webform_test_message_custom.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_options/config/install/webform.webform.test_options.yml b/web/modules/webform/tests/modules/webform_test_options/config/install/webform.webform.test_options.yml
index 64c0d814f9..2778609050 100644
--- a/web/modules/webform/tests/modules/webform_test_options/config/install/webform.webform.test_options.yml
+++ b/web/modules/webform/tests/modules/webform_test_options/config/install/webform.webform.test_options.yml
@@ -333,6 +333,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -383,3 +384,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test_options/webform_test_options.info.yml b/web/modules/webform/tests/modules/webform_test_options/webform_test_options.info.yml
index 25731ffa2f..d36d532151 100644
--- a/web/modules/webform/tests/modules/webform_test_options/webform_test_options.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_options/webform_test_options.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_paragraphs/webform_test_paragraphs.info.yml b/web/modules/webform/tests/modules/webform_test_paragraphs/webform_test_paragraphs.info.yml
index 8026870fbe..efaae741ad 100644
--- a/web/modules/webform/tests/modules/webform_test_paragraphs/webform_test_paragraphs.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_paragraphs/webform_test_paragraphs.info.yml
@@ -7,7 +7,7 @@ dependencies:
   - 'paragraphs:paragraphs'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_rest/webform_test_rest.info.yml b/web/modules/webform/tests/modules/webform_test_rest/webform_test_rest.info.yml
index 523f606ff0..7674d0d696 100644
--- a/web/modules/webform/tests/modules/webform_test_rest/webform_test_rest.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_rest/webform_test_rest.info.yml
@@ -9,7 +9,7 @@ dependencies:
   - 'drupal:serialization'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_submissions/config/install/webform.webform.test_submissions.yml b/web/modules/webform/tests/modules/webform_test_submissions/config/install/webform.webform.test_submissions.yml
index 4611443175..565a611fd1 100644
--- a/web/modules/webform/tests/modules/webform_test_submissions/config/install/webform.webform.test_submissions.yml
+++ b/web/modules/webform/tests/modules/webform_test_submissions/config/install/webform.webform.test_submissions.yml
@@ -172,6 +172,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -222,3 +223,4 @@ access:
     users: {  }
     permissions: {  }
 handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test_submissions/webform_test_submissions.info.yml b/web/modules/webform/tests/modules/webform_test_submissions/webform_test_submissions.info.yml
index a7e8d80a72..a1cb7bed57 100644
--- a/web/modules/webform/tests/modules/webform_test_submissions/webform_test_submissions.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_submissions/webform_test_submissions.info.yml
@@ -7,7 +7,7 @@ dependencies:
   - 'drupal:node'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_third_party_settings/webform_test_third_party_settings.info.yml b/web/modules/webform/tests/modules/webform_test_third_party_settings/webform_test_third_party_settings.info.yml
index b7676a18eb..d59e641d7e 100644
--- a/web/modules/webform/tests/modules/webform_test_third_party_settings/webform_test_third_party_settings.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_third_party_settings/webform_test_third_party_settings.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_translation/config/install/webform.webform.test_translation.yml b/web/modules/webform/tests/modules/webform_test_translation/config/install/webform.webform.test_translation.yml
index 08fa2e0741..437943f925 100644
--- a/web/modules/webform/tests/modules/webform_test_translation/config/install/webform.webform.test_translation.yml
+++ b/web/modules/webform/tests/modules/webform_test_translation/config/install/webform.webform.test_translation.yml
@@ -62,7 +62,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': 'Send message'
-
+  
 css: ''
 javascript: ''
 settings:
@@ -176,6 +176,7 @@ settings:
   purge_days: null
   results_disabled: false
   results_disabled_ignore: false
+  results_customize: false
   token_view: false
   token_update: false
 access:
@@ -262,3 +263,4 @@ handlers:
       return_path: ''
       sender_mail: ''
       sender_name: ''
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test_translation/webform_test_translation.info.yml b/web/modules/webform/tests/modules/webform_test_translation/webform_test_translation.info.yml
index f01e17d910..28dfe00f59 100644
--- a/web/modules/webform/tests/modules/webform_test_translation/webform_test_translation.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_translation/webform_test_translation.info.yml
@@ -9,7 +9,7 @@ dependencies:
   - 'drupal:locale'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_translation_lingotek/webform_test_translation_lingotek.info.yml b/web/modules/webform/tests/modules/webform_test_translation_lingotek/webform_test_translation_lingotek.info.yml
index 61c1d67139..640e7731d4 100644
--- a/web/modules/webform/tests/modules/webform_test_translation_lingotek/webform_test_translation_lingotek.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_translation_lingotek/webform_test_translation_lingotek.info.yml
@@ -10,7 +10,7 @@ dependencies:
   - 'lingotek:lingotek'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_validate/webform_test_validate.info.yml b/web/modules/webform/tests/modules/webform_test_validate/webform_test_validate.info.yml
index 191ee38474..6475adaeb9 100644
--- a/web/modules/webform/tests/modules/webform_test_validate/webform_test_validate.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_validate/webform_test_validate.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_variant/webform_test_variant.info.yml b/web/modules/webform/tests/modules/webform_test_variant/webform_test_variant.info.yml
index 8192f956ac..f804b098b5 100644
--- a/web/modules/webform/tests/modules/webform_test_variant/webform_test_variant.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_variant/webform_test_variant.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_views/webform_test_views.info.yml b/web/modules/webform/tests/modules/webform_test_views/webform_test_views.info.yml
index cc2bf0a70e..53f527e462 100644
--- a/web/modules/webform/tests/modules/webform_test_views/webform_test_views.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_views/webform_test_views.info.yml
@@ -9,7 +9,7 @@ dependencies:
   - 'drupal:views'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/modules/webform_test_wizard_custom/webform_test_wizard_custom.info.yml b/web/modules/webform/tests/modules/webform_test_wizard_custom/webform_test_wizard_custom.info.yml
index 137ee110d0..aa4926483b 100644
--- a/web/modules/webform/tests/modules/webform_test_wizard_custom/webform_test_wizard_custom.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_wizard_custom/webform_test_wizard_custom.info.yml
@@ -6,7 +6,7 @@ core_version_requirement: ^8.7.7 || ^9
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementCodeMirrorTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementCodeMirrorTest.php
index 69780f0502..f8c8a2e085 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementCodeMirrorTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementCodeMirrorTest.php
@@ -44,12 +44,15 @@ public function testCodeMirror() {
     $this->assertRaw('<label for="edit-yaml-basic">yaml_basic</label>');
     $this->assertRaw('<textarea data-drupal-selector="edit-yaml-basic" class="js-webform-codemirror webform-codemirror yaml form-textarea resize-vertical" data-webform-codemirror-mode="text/x-yaml" id="edit-yaml-basic" name="yaml_basic" rows="5" cols="60">test: hello</textarea>');
 
-    // Check associative array as the #default_value.
+    // Check default value decoding.
     $this->drupalPostForm('/webform/test_element_codemirror', [], t('Submit'));
-    $this->assertRaw('yaml_array:
+    $this->assertRaw("yaml_basic: 'test: hello'
+yaml_array:
   one: One
   two: Two
-  three: Three');
+  three: Three
+yaml_decode_value:
+  test: hello");
 
     // Check invalid YAML.
     $edit = [
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementCounterTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementCounterTest.php
index 0855dbe6c5..9bbd66851f 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementCounterTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementCounterTest.php
@@ -28,6 +28,9 @@ public function testCounter() {
     $this->assertRaw('<textarea data-counter-type="word" data-counter-minimum="5" data-counter-minimum-message="%d word(s) entered. This is custom text" class="js-webform-counter webform-counter form-textarea resize-vertical" data-drupal-selector="edit-counter-words-min-message" id="edit-counter-words-min-message" name="counter_words_min_message" rows="5" cols="60"></textarea>');
     $this->assertRaw('<textarea data-counter-type="word" data-counter-maximum="10" data-counter-maximum-message="%d character(s) remaining. This is custom text" class="js-webform-counter webform-counter form-textarea resize-vertical" data-drupal-selector="edit-counter-words-max-message" id="edit-counter-words-max-message" name="counter_words_max_message" rows="5" cols="60"></textarea>');
 
+    // Check counter for XSS.
+    $this->assertRaw('<input data-counter-type="character" data-counter-minimum="5" data-counter-minimum-message="alert(&#039;XSS&#039;);&lt;em&gt;%d&lt;/em&gt; character(s) entered." data-counter-maximum="10" data-counter-maximum-message="alert(&#039;XSS&#039;);&lt;em&gt;%d&lt;/em&gt; character(s) remaining." class="js-webform-counter webform-counter form-text" data-drupal-selector="edit-counter-characters-xss" type="text" id="edit-counter-characters-xss" name="counter_characters_xss" value="" size="60" maxlength="10" />');
+
     // Check counter min/max validation error (min: 5 / max: 10).
     $edit = [
       'counter_characters_min' => '123',
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementFormatTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementFormatTest.php
index ac50c90b12..580e2dd55c 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementFormatTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementFormatTest.php
@@ -181,6 +181,7 @@ public function testFormat() {
       'Checkboxes (And)' => 'One, Two, and Three',
       'Checkboxes (Ordered list)' => '<div class="item-list"><ol><li>One</li><li>Two</li><li>Three</li></ol>',
       'Checkboxes (Unordered list)' => '<div class="item-list"><ul><li>One</li><li>Two</li><li>Three</li></ul>',
+      'Checkboxes (Checklist)' => '<span style="font-size: 1.4em; line-height: 1em">☑</span> One<br /><span style="font-size: 1.4em; line-height: 1em">☑</span> Two<br /><span style="font-size: 1.4em; line-height: 1em">☑</span> Three<br />',
     ];
     foreach ($elements as $label => $value) {
       $this->assertContains('<b>' . $label . '</b><br />' . $value, $body, new FormattableMarkup('Found @label: @value', [
@@ -214,6 +215,10 @@ public function testFormat() {
 - One
 - Two
 - Three',
+      'Checkboxes (Checklist):
+☑ One
+☑ Two
+☑ Three',
     ];
     foreach ($elements as $value) {
       $this->assertContains($value, $body, new FormattableMarkup('Found @value', ['@value' => $value]));
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementIgnoredPropertiesTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementIgnoredPropertiesTest.php
index 9995a8aff1..83a1813bea 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementIgnoredPropertiesTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementIgnoredPropertiesTest.php
@@ -26,8 +26,9 @@ class WebformElementIgnoredPropertiesTest extends WebformElementBrowserTestBase
   public function testIgnoredProperties() {
     $webform_ignored_properties = Webform::load('test_element_ignored_properties');
     $elements = $webform_ignored_properties->getElementsInitialized();
+    $this->assert(isset($elements['textfield']));
     foreach (WebformElementHelper::$ignoredProperties as $ignored_property) {
-      $this->assert(!isset($elements['test'][$ignored_property]), new FormattableMarkup('@property ignored.', ['@property' => $ignored_property]));
+      $this->assert(!isset($elements['textfield'][$ignored_property]), new FormattableMarkup('@property ignored.', ['@property' => $ignored_property]));
     }
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileLimitTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileLimitTest.php
index dc3e4e6750..e73862348c 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileLimitTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileLimitTest.php
@@ -79,6 +79,16 @@ public function testLimits() {
     ];
     $this->postSubmission($webform, $edit);
     $this->assertRaw('This form\'s file upload quota of <em class="placeholder">2 KB</em> has been exceeded. Please remove some files.');
+
+    // Check invalid composite file upload.
+    $edit = [
+      'files[managed_file_01]' => \Drupal::service('file_system')->realpath($file->uri),
+      'files[custom_composite_managed_files_items_0_managed_file]' => \Drupal::service('file_system')->realpath($file->uri),
+      'files[custom_composite_managed_files_items_1_managed_file]' => \Drupal::service('file_system')->realpath($file->uri),
+    ];
+    $this->drupalPostForm('/webform/test_element_managed_file_limit', [], t('Add'));
+    $this->drupalPostForm(NULL, $edit, t('Submit'));
+    $this->assertRaw('This form\'s file upload quota of <em class="placeholder">2 KB</em> has been exceeded. Please remove some files.');
   }
 
 }
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileTest.php
index 2aadfad830..ef1a39b026 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileTest.php
@@ -119,6 +119,25 @@ public function testFileUpload() {
     $this->drupalGet('/webform/test_element_managed_file/test');
     $this->assertNoRaw('<div class="webform-managed-file-placeholder managed-file-placeholder js-form-wrapper form-wrapper" data-drupal-selector="edit-managed-file-single-placeholder-file-placeholder" id="edit-managed-file-single-placeholder-file-placeholder">This is the single file upload placeholder</div>');
     $this->assertNoRaw('<div class="webform-managed-file-placeholder managed-file-placeholder js-form-wrapper form-wrapper" data-drupal-selector="edit-managed-file-multiple-placeholder-file-placeholder" id="edit-managed-file-multiple-placeholder-file-placeholder">This is the multiple file upload placeholder</div>');
+
+
+    $this->drupalLogout();
+
+    /* Required error */
+
+    // Set required error.
+    /** @var \Drupal\webform\WebformInterface $webform */
+    $webform = Webform::load('test_element_managed_file');
+    $webform->setElementProperties('managed_file_single', $webform->getElementDecoded('managed_file_single') + [
+      '#required' => TRUE,
+      '#required_error' => '{Custom required error}',
+    ]);
+    $webform->save();
+
+    // Check that required error is displayed.
+    $this->postSubmission($webform);
+    $this->assertRaw('<h2 class="visually-hidden">Error message</h2>');
+    $this->assertRaw('{Custom required error}');
   }
 
   /**
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementMediaFileTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementMediaFileTest.php
index 4edcc3e1cf..8365d85b9b 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementMediaFileTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementMediaFileTest.php
@@ -45,7 +45,7 @@ public function testMediaFileUpload() {
     $this->assertRaw('<input data-drupal-selector="edit-image-file-upload" accept="image/*" type="file" id="edit-image-file-upload" name="files[image_file]" size="22" class="js-form-file form-file" />');
 
     // Check video file.
-    $this->assertRaw('<input data-drupal-selector="edit-video-file-upload" accept="video/*" type="file" id="edit-video-file-upload" name="files[video_file]" size="22" class="js-form-file form-file" />');
+    $this->assertRaw('<input data-drupal-selector="edit-video-file-upload" accept="video/mp4,video/x-m4v,video/*" type="file" id="edit-video-file-upload" name="files[video_file]" size="22" class="js-form-file form-file" />');
 
     /* Element processing */
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementPluginDefinitionsTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementPluginDefinitionsTest.php
index 44db886ea3..56c5d7d019 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementPluginDefinitionsTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementPluginDefinitionsTest.php
@@ -44,11 +44,14 @@ class WebformElementPluginDefinitionsTest extends WebformElementBrowserTestBase
   public function testElementDefinitions() {
     // Comparing all element's expected and actual definitions ensures
     // that there are not unexpected changes to any element's definitions.
-    $expected_elements = $this->getExpectedElementDefinitions();
-    $actual_elements = $this->getActualElementDefinitions();
-    $this->htmlOutput('<pre>' . htmlentities(Yaml::encode($actual_elements)) . '</pre>');
-    foreach ($actual_elements as $element_key => $actual_element) {
-      $this->assertEquals($expected_elements[$element_key], $actual_element, "Expected and actual '$element_key' element definitions match.");
+    $expected_definitions = $this->getExpectedElementDefinitions();
+    $actual_definitions = $this->getActualElementDefinitions();
+    $this->htmlOutput('<pre>' . htmlentities(Yaml::encode($actual_definitions)) . '</pre>');
+    foreach ($actual_definitions as $key => $actual_definition) {
+      if ($expected_definitions[$key] != $actual_definition) {
+        $this->htmlOutput('<pre>' . Yaml::encode([$key => $actual_definition]) . '</pre>');
+      }
+      $this->assertEquals($expected_definitions[$key], $actual_definition, "Expected and actual '$key' element definitions match.");
     }
   }
 
@@ -1807,6 +1810,63 @@ class: Drupal\webform\Plugin\WebformElement\WebformWizardPage
   container: true
   root: true
   multiple: false
+webform_table:
+  dependencies: {  }
+  default_key: ''
+  category: Containers
+  description: 'Provides an element to render a table.'
+  hidden: false
+  multiline: false
+  composite: false
+  states_wrapper: false
+  deprecated: false
+  deprecated_message: ''
+  id: webform_table
+  label: Table
+  class: Drupal\webform\Plugin\WebformElement\WebformTable
+  provider: webform
+  input: false
+  container: true
+  root: false
+  multiple: false
+webform_table_row:
+  dependencies: {  }
+  default_key: ''
+  category: 'Containers'
+  description: 'Provides an element to render a table row.'
+  hidden: true
+  multiline: false
+  composite: false
+  states_wrapper: false
+  deprecated: false
+  deprecated_message: ''
+  id: webform_table_row
+  label: 'Table row'
+  class: Drupal\webform\Plugin\WebformElement\WebformTableRow
+  provider: webform
+  input: false
+  container: true
+  root: false
+  multiple: false
+webform_scale:
+  dependencies: {  }
+  default_key: ''
+  category: 'Advanced elements'
+  description: 'Provides a form element for input of a numeric scale.'
+  id: webform_scale
+  label: Scale
+  class: Drupal\webform\Plugin\WebformElement\WebformScale
+  provider: webform
+  input: true
+  container: false
+  root: false
+  multiple: false
+  hidden: false
+  multiline: false
+  composite: false
+  states_wrapper: false
+  deprecated: false
+  deprecated_message: ''
 YAML;
 
     return Yaml::decode($yaml);
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementPluginPropertiesTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementPluginPropertiesTest.php
index 4517990bfd..64a6926167 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementPluginPropertiesTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementPluginPropertiesTest.php
@@ -49,6 +49,9 @@ public function testElementDefaultProperties() {
     $actual_elements = $this->getActualElementDefaultProperties();
     $this->htmlOutput('<pre>' . htmlentities(Yaml::encode($actual_elements)) . '</pre>');
     foreach ($actual_elements as $element_key => $actual_element) {
+      if ($expected_elements[$element_key] != $actual_element) {
+        $this->htmlOutput('<pre>' . Yaml::encode([$element_key => $actual_element]) . '</pre>');
+      }
       $this->assertEquals($expected_elements[$element_key], $actual_element, "Expected and actual '$element_key' element properties match.");
     }
   }
@@ -979,7 +982,7 @@ protected function getExpectedElementDefaultProperties() {
   disabled: false
   field_prefix: ''
   field_suffix: ''
-  file_extensions: 'gif jpg jpeg png bmp eps tif pict psd txt rtf html odf pdf doc docx ppt pptx xls xlsx xml avi mov mp3 ogg wav bz2 dmg gz jar rar sit svg tar zip'
+  file_extensions: 'gif jpg jpeg png bmp eps tif pict psd txt rtf html odf pdf doc docx ppt pptx xls xlsx xml avi mov mp3 mp4 ogg wav bz2 dmg gz jar rar sit svg tar zip'
   file_help: ''
   file_name: ''
   file_placeholder: ''
@@ -1437,11 +1440,22 @@ protected function getExpectedElementDefaultProperties() {
   international_initial_country: ''
   international_preferred_countries: {  }
   label_attributes: {  }
-  maxlength: ''
-  minlength: ''
+  maxlength: null
+  minlength: null
   more: ''
   more_title: ''
   multiple: false
+  multiple__add_more: true
+  multiple__add_more_button_label: Add
+  multiple__add_more_input: true
+  multiple__add_more_input_label: 'more items'
+  multiple__add_more_items: 1
+  multiple__empty_items: 1
+  multiple__header_label: ''
+  multiple__min_items: null
+  multiple__no_items_message: 'No items entered. Please add items below.'
+  multiple__operations: true
+  multiple__sorting: true
   pattern: ''
   pattern_error: ''
   placeholder: ''
@@ -1450,7 +1464,7 @@ protected function getExpectedElementDefaultProperties() {
   readonly: false
   required: false
   required_error: ''
-  size: ''
+  size: null
   states: {  }
   states_clear: true
   title: ''
@@ -4711,10 +4725,6 @@ protected function getExpectedElementDefaultProperties() {
     - authenticated
   access_view_users: {  }
   access_view_permissions: {  }
-
-
-
-
 webform_toggles:
   toggle_theme: light
   toggle_size: medium
@@ -4771,6 +4781,132 @@ protected function getExpectedElementDefaultProperties() {
     - authenticated
   access_view_users: {  }
   access_view_permissions: {  }
+webform_table:
+  access_create_permissions: {  }
+  access_create_roles:
+    - anonymous
+    - authenticated
+  access_create_users: {  }
+  access_update_permissions: {  }
+  access_update_roles:
+    - anonymous
+    - authenticated
+  access_update_users: {  }
+  access_view_permissions: {  }
+  access_view_roles:
+    - anonymous
+    - authenticated
+  access_view_users: {  }
+  admin_title: ''
+  attributes: {  }
+  caption: ''
+  default_value: ''
+  description: ''
+  description_display: ''
+  field_prefix: ''
+  field_suffix: ''
+  flex: 1
+  format: table
+  format_attributes: {  }
+  format_html: ''
+  format_text: ''
+  header: {  }
+  help: ''
+  help_display: ''
+  help_title: ''
+  label_attributes: {  }
+  more: ''
+  more_title: ''
+  prefix_children: true
+  private: false
+  required: false
+  required_error: ''
+  states: {  }
+  states_clear: true
+  sticky: false
+  title: ''
+  title_display: ''
+  wrapper_attributes: {  }
+webform_table_row:
+  access_create_permissions: {  }
+  access_create_roles:
+    - anonymous
+    - authenticated
+  access_create_users: {  }
+  access_update_permissions: {  }
+  access_update_roles:
+    - anonymous
+    - authenticated
+  access_update_users: {  }
+  access_view_permissions: {  }
+  access_view_roles:
+    - anonymous
+    - authenticated
+  access_view_users: {  }
+  admin_title: ''
+  attributes: {  }
+  flex: 1
+  private: false
+  states: {  }
+  states_clear: true
+  title: ''
+webform_scale:
+  access_create_permissions: {  }
+  access_create_roles:
+    - anonymous
+    - authenticated
+  access_create_users: {  }
+  access_update_permissions: {  }
+  access_update_roles:
+    - anonymous
+    - authenticated
+  access_update_users: {  }
+  access_view_permissions: {  }
+  access_view_roles:
+    - anonymous
+    - authenticated
+  access_view_users: {  }
+  admin_title: ''
+  attributes: {  }
+  default_value: ''
+  description: ''
+  description_display: ''
+  disabled: false
+  field_prefix: ''
+  field_suffix: ''
+  flex: 1
+  format: value
+  format_attributes: {  }
+  format_html: ''
+  format_text: ''
+  help: ''
+  help_display: ''
+  help_title: ''
+  label_attributes: {  }
+  max: 5
+  max_text: ''
+  min: 1
+  min_text: ''
+  more: ''
+  more_title: ''
+  prepopulate: false
+  private: false
+  readonly: false
+  required: false
+  required_error: ''
+  scale_size: medium
+  scale_text: below
+  scale_type: circle
+  states: {  }
+  states_clear: true
+  title: ''
+  title_display: ''
+  unique: false
+  unique_entity: false
+  unique_error: ''
+  unique_user: false
+  wrapper_attributes: {  }
+  wrapper_type: fieldset
 YAML;
     return Yaml::decode($yaml);
   }
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementPrepopulateTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementPrepopulateTest.php
index c48c69741b..714f56d38a 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementPrepopulateTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementPrepopulateTest.php
@@ -37,31 +37,59 @@ public function testElementPrepopulate() {
 
     $files = $this->getTestFiles('text');
 
-    // Check prepopulation of an element.
+    // Check default value of elements on multiple_values.
     $this->drupalGet('/webform/test_element_prepopulate');
-    $this->assertFieldByName('textfield', '');
-    $this->assertFieldByName('textfield_prepopulate', '');
-    $this->assertFieldByName('files[managed_file_prepopulate]', '');
+    $this->assertFieldByName('textfield_01', '');
+    $this->assertFieldByName('textfield_prepopulate_01', '{default_value_01}');
+    $this->assertFieldByName('files[managed_file_prepopulate_01]', '');
+    $this->drupalPostForm('/webform/test_element_prepopulate', [], t('Next Page >'));
+    $this->assertFieldByName('textfield_02', '');
+    $this->assertFieldByName('textfield_prepopulate_02', '{default_value_02}');
 
     // Check 'textfield' can not be prepopulated.
-    $this->drupalGet('/webform/test_element_prepopulate', ['query' => ['textfield' => 'value']]);
-    $this->assertNoFieldByName('textfield', 'value');
+    $this->drupalGet('/webform/test_element_prepopulate', ['query' => ['textfield_01' => 'value']]);
+    $this->assertNoFieldByName('textfield_0', 'value');
 
-    // Check 'textfield_prepopulate' can be prepopulated.
-    $this->drupalGet('/webform/test_element_prepopulate', ['query' => ['textfield_prepopulate' => 'value']]);
-    $this->assertFieldByName('textfield_prepopulate', 'value');
+    // Check prepopulating textfield on multiple pages.
+    $options = [
+      'query' => [
+        'textfield_prepopulate_01' => 'value_01',
+        'textfield_prepopulate_02' => 'value_02',
+      ],
+    ];
+    $this->drupalGet('/webform/test_element_prepopulate', $options);
+    $this->assertFieldByName('textfield_prepopulate_01', 'value_01');
+    $this->drupalPostForm('/webform/test_element_prepopulate', [], t('Next Page >'), $options);
+    $this->assertFieldByName('textfield_prepopulate_02', 'value_02');
+
+    // Check prepopulating textfield on multiple pages and changing the value
+    $options = [
+      'query' => [
+        'textfield_prepopulate_01' => 'value_01',
+        'textfield_prepopulate_02' => 'value_02',
+      ],
+    ];
+    $this->drupalGet('/webform/test_element_prepopulate', $options);
+    $this->assertFieldByName('textfield_prepopulate_01', 'value_01');
+    $this->drupalPostForm('/webform/test_element_prepopulate', ['textfield_prepopulate_01' => 'edit_01'], t('Next Page >'), $options);
+    $this->assertFieldByName('textfield_prepopulate_02', 'value_02');
+    $this->drupalPostForm(NULL, [], t('< Previous Page'), $options);
+    $this->assertNoFieldByName('textfield_prepopulate_01', 'value_01');
+    $this->assertFieldByName('textfield_prepopulate_01', 'edit_01');
 
     // Check 'managed_file_prepopulate' can not be prepopulated.
     // The #prepopulate property is not available to managed file elements.
     // @see \Drupal\webform\Plugin\WebformElement\WebformManagedFileBase::defaultProperties
     $edit = [
-      'files[managed_file_prepopulate]' => \Drupal::service('file_system')->realpath($files[0]->uri),
+      'files[managed_file_prepopulate_01]' => \Drupal::service('file_system')->realpath($files[0]->uri),
     ];
-    $sid = $this->postSubmission($webform, $edit);
+    $this->drupalPostForm('/webform/test_element_prepopulate', $edit, t('Next Page >'));
+    $this->drupalPostForm(NULL, [], t('Submit'));
+    $sid = $this->getLastSubmissionId($webform);
     $webform_submission = WebformSubmission::load($sid);
-    $fid = $webform_submission->getElementData('managed_file_prepopulate');
-    $this->drupalGet('/webform/test_element_prepopulate', ['query' => ['managed_file_prepopulate' => $fid]]);
-    $this->assertFieldByName('files[managed_file_prepopulate]', '');
+    $fid = $webform_submission->getElementData('managed_file_prepopulate_01');
+    $this->drupalGet('/webform/test_element_prepopulate', ['query' => ['managed_file_prepopulate_01' => $fid]]);
+    $this->assertFieldByName('files[managed_file_prepopulate_01]', '');
   }
 
 }
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementScaleTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementScaleTest.php
new file mode 100644
index 0000000000..76897b1d0c
--- /dev/null
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementScaleTest.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Drupal\Tests\webform\Functional\Element;
+
+/**
+ * Tests for scale element.
+ *
+ * @group Webform
+ */
+class WebformElementScaleTest extends WebformElementBrowserTestBase {
+
+  /**
+   * Webforms to load.
+   *
+   * @var array
+   */
+  protected static $testWebforms = ['test_element_scale'];
+
+  /**
+   * Test scale element.
+   */
+  public function testRating() {
+    $this->drupalGet('/webform/test_element_scale');
+
+    // Check basic scale element.
+    $this->assertRaw('<div class="webform-scale webform-scale-circle webform-scale-medium webform-scale-1-to-5">');
+    $this->assertRaw('<input data-drupal-selector="edit-scale-1" class="webform-scale-1 visually-hidden form-radio" type="radio" id="edit-scale-1" name="scale" value="1" />');
+
+    // Check scale with text element.
+    $this->assertRaw('<div class="webform-scale webform-scale-circle webform-scale-medium webform-scale-0-to-10">');
+    $this->assertRaw('<input data-drupal-selector="edit-scale-text-0" class="webform-scale-0 visually-hidden form-radio" type="radio" id="edit-scale-text-0" name="scale_text" value="0" />');
+    $this->assertRaw('<div class="webform-scale-text webform-scale-text-below"><div class="webform-scale-text-min">0 = disagree</div><div class="webform-scale-text-max">agree = 10</div></div></div></div>');
+
+    // Check processing.
+    $edit = [
+      'scale' => 1,
+      'scale_text' => 2,
+    ];
+    $this->drupalPostForm('/webform/test_element_scale', $edit, t('Submit'));
+    $this->assertRaw("scale: '1'
+scale_text: '2'
+scale_text_above: null
+scale_small: null
+scale_medium: null
+scale_large: null
+scale_square: null
+scale_flexbox: null");
+  }
+
+}
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementSignatureTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementSignatureTest.php
index c36d4fa72d..c22abe4edc 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementSignatureTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementSignatureTest.php
@@ -51,15 +51,57 @@ public function testSignature() {
     $this->assertTrue(file_exists("$signature_directory/$sid"));
     $this->assertEqual(count(file_scan_directory($signature_directory, '/^signature-.*\.png$/')), 1);
 
+    /**************************************************************************/
+    // Validation.
+    /**************************************************************************/
+
+    // Check valid signature.
+    $this->assertSignature('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAqkAAADjCAYAAACmeo3kAAAgAElEQVR4Xu19CfA3RXnmEw9QDlkRUTxwA8aoIKzitfHaNasYFUlKN4paIet9JOUmkUI3HokmitHo5lAxEYlZCVaihQca1C1dD7a8ool4lEZgVYJGVBIREY+49cB08n7v1/Obnp7umT7eqbL8+P/6fLqn5+n3/AnYYwgYAoaAIdAyAj8P4McA3tryJG1uhoAh0B4CP9HelGxGhoAhYAgYAgMClwC45fDvbwI4xJAxBAwBQ6AWBIyk1rJSNk5DwBAwBOYh8B8AfFJVuVSQ1nmtWWlDwBAwBFZGwEjqyoBbd4aAIWAIrITAkwC8xtPXnQH87UpjsG4MAUPAEIhGwEhqNHRW0RAwBAyBohF4AoA/9YzwrwE8uOiR2+AMAUPAEABgJNW2gSFgCBgCbSLwKABnj0ztvgA+2Oa0bVaGgCHQCgJGUltZSZuHIWAIGAJ7IvDvAVw8AsrrAfyyAWYIGAKGQMkIGEkteXVsbIaAIWAILEPgbQBO8DTxAwD7LGvaahsChoAhkBcBI6l58bXWDQFDwBDYGoELABztGcQvAHjL1oOz/g0BQ8AQGEPASKrtDUPAEDAE2kaAwfzP8UzxtwH8VttTt9kZAoZAzQgYSa159WzshoAhYAiEIfCfAPwugJ8Rxb8G4LCw6lbKEDAEDIH1ETCSuj7m1qMhYAgYAlsg4Iub+pMA/t8Wg7E+DQFDwBCYQsBI6hRC9rshYAgYAm0g4MtA9d8A/Fkb07NZGAKGQGsIGEltbUVtPoaAIWAIjCPwY/WThaKy3WIIGALFImAktdilsYEZAoaAIZAcgSsB7CdafT8A2qvaszcC/w7AicOf3wrgnwwkQ8AQWBcBI6nr4m29GQKGgCGwJQJfBXBzMYCvA7jZlgMquO9LhWPZZQAOLXisNjRDoEkEjKQ2uaw2KUPAEDAEvAj8TwDPEL9YUH//RvHZ7zLe7DG2rwwBQ2A9BIykroe19WQIGAKGwNYI+FKl2ndg71V5IYDneBaLTmZ0Nuv9MVOI3nfASvO3w2kloK0bQ8AQMAQKQYCq60PEWH4dwCsKGVspw3gwgHeMDIYhuxi6q+fnnwHcaADgcgB3sVBmPW+HfHM3kpoPW2vZECgNAUrRHgXgTgA+AeCMTpxBKPU5afiQct5ndzLvsf1HknUb8aORLj9S2slMlrozgL8t7QVfaTx0tHuf6usKQVpXGoZ10wMCRlJ7WGWboyFwLQLfBnCgAOPLiqy0ilOv8x5bT+08xXI9k64xnJ4G4JUjP14C4NatvjAT8xqTMv8aANo822MIJEPASGoyKK0hQ6BoBB4D4A2eEbZOTnqd967N+HEAx6kCfwDgvxe9g7cZ3LsBPGCka9qtPm+bYW3aK7Ux1Ebo5/sA9t10ZNZ5cwgYSW1uSW1ChoAXAX5Mf9vzy0MAvLNhzHqd964l/T8A7qcKMAbojRveB7FTG7vksL1eVdy77HUtg1nsTrN6XgSMpNrGMAT6QICquJd3SFJ/HsA5Hc57Lkll+ecC+J0+XodZs6SEmRc85ygkK58F4LGzWqu/8C6SytnxsmOJD+pf5yJmYCS1iGWwQRgC2RHwOTuw09YlqY8E8EYPuscC+FR21Mvs4MMA7uEZGm2UiYsRjL3B4WXnBYPTof71PwOgdLqXZ4qkng/g3r2AYfPMi4CR1Lz4WuuGQCkIjH1Y7gPgQ6UMMsM4xubd89n3RQBHDlhfrewIzTZ1fBMySgTDLennswCOyrB3S21yDAc5XosnW+rqVTaung/qypbKhjuCAMMqyfzaDKdjz94IjElSW5cojs2757NPSlIZRonZleRjdoXjJ8irATzF8/PLAJzS0cHzQwDXHeb7L8P/X0fN/y0AfqEjTGyqGRDo+aDOAKc1uQEC3wGw/9Av/y1DLG0wnGK7ZDrHv/OMjkHJWyb2PpLKD+z1i12p/AOTjlPvH+J9ylSpVPcz6kPL+yIWZV+6VLbFMGcnAyAx6+GR0vgLB1tmhp86SE3ewlL1sBsyztFIakZwrensCDwRwJ+oXp4E4E+z91xfB2Mf19adHBi0XpOtqwDsV98SJhuxJqm0t6REVQb4ZxnaWtqzJwK0tfzgCCgk98SshyD/tF92cWJJUm87hDDTmcu+O5hC2IXH3qQoBIykRsFmlQpBgF7b/MDKx1RM/sUZk6S2TlJ9ueopBfqpQvbwFsPQJJXSZuJEciUlYScAOHeLARbcp+/SI4dLDElUW3c+kyYjHwFwzwGEXwbwW54LD9X+rWNS8Latd2hGUutdOxs5QDuw31BA/D6AZxo4eyHgk6TSlszZlbUKmY+cM3f9oa1OOGBeuwjGmaI+CRfV/vb8GwIhTkOvB0Cy1vLju+i4+fLCczqA4wUA5pDX8m7IODcjqRnBtaazI/D84dYuO+It3he0PvtgCu/AR9Z6yBDjIxVfB3Czwtcr5/C0PSFVte55r1Lzt56RbC7Ovv1EQqadqSg5bNk+dRdJJabEiR7+zqmVf+stVNfcvWXlPQgYSbVtUTMCjwNwhprA4wG8ruZJZRq7T5LK8EM3yNRfSc2SLMiPZe+OU2OSVK6ZTn5g5jN77mTfe0TnQzoNyT1GKTSJaqu2mH8B4KQBGqZIfbTnhdcmJMSClx5T+5d0OhY+FiOphS+QDW8nAv8VwF+qEr8I4K8Mt70QGLNJ7eEM8KW2bN0Wd9crMCUF+xEAF06od6mzxtFn4+zSyb4bwN1EhZbNJT4pQpftmifNHqQJian97eM0C4EePlCzALHCVSHAQPQfUCO+7w7v26oml3iwY979vZwBP1Z4Gkm9FpC3epwPPw/gdgIvU/nvuXn0XnLvEAksLwAySkKrkugQSapDjSSW8Zj5/ADA3TuJgJD4CO+zuV4+UH2ubvuzvpcnW1LrweljV9VHUr8J4JDYBiuq57MjbD0+7K7lmSIYzFUvQwmZ9CuMpLKUlhzyby3aYtLelHFh+Uw5iulYxa0S94qOxHqGaiS1nrWyke6NwBM8MVFN6uPfKT6i9j0AN+xgY/lUtD2ffVOqWo0XbQlJ6u25FgFpDuGLkEH7VJkcocWYs3KOIZcY+gkwk5l7LMi/vU1BCPR8UAcBZIWKRoBetU9WIzSSGk5SrwRwQNErnG5wUkXLf+sUjul6Kr+ldwB48DDMdwJ4iGfIUkXLn3uWPGt4xtT9spzGj05Gbyx/awSPkFFUGF2FD6Op8L93Pbwkk6w7tT8vPpQwt+pYFgykFdyNgJFU2yE1I3ABgKPVBHq2NZz6SFzuKdDLGUCp8b5i/i2qYEPf5SnHKbajVf6UhDFyhj1ACEnVKu7WpKlzSSr3jY4cESKBtf3WOQK9fKA6X+Zmp8+Ue1pdbSTVv9w+df9nh5SFzW4QMbGLlMr674R3cg/zl3MMIala5U9nqtv3BtTIfKW6f1es4bcBYNYu97R0MZJ2zQwDSNOrkEfuPZY3zVcIah2XMZLa8eI3MHUt0eCUbE+PL6zG62ODp20DW2FyCn8/5Bd3Ba8CsN9krTYLSKLg8+53s34fAEoEWyRZS1Y2RJLK9jXR34X1kvFsUTdGkspxagfOlsN0bbEuzfVpH/TmlrSbCfmcYTh5k6T6t4BPksr4hUyI0MPzIQCMBiGfXu0sQ0mqVs+2RLKW7PlQkso+pBd8S+dTLEklBtqxjA5VxMkeQ2AvBIyk2qaoFQFfqBfOxfb0+Irqj2vrqRslElrNyN96/ThOhaCSuNGxRcb97JXYS0zmkFRtm9rKnltCUnlhpgTV7atvATjOnKhq/RTnHbd90PPia63nQ+AjI6pqk6SGk9SesPKR1BCv5Hw7eLuWp0JQyZGZA9Xe6zQVgkrXkES/FWn0EpJKfLTa32KnbnceFN2zkdSil8cGN4LAmKrfJKm7t4z8uPYWhslHUj8N4E4dvmUhIagcLNpMxByowrz75bbS6u0WvrtLSSrxeQGA5wqger00dngEhU+5hZclfLZWshUEeOs+cWQytqfHV5mBxx0+jIywfysbImAePpJKNeNNAuq2ViTEu1/OmTnpHyD+0JME3rf2c9T9PqlhCzFTU5BUXoB4lt9vAPmfANAEifvTHkPgGgTsg24boTYEtI0XiZcLzL4rHExt80w9Xq1e642kfhjAPTyg9mhjOZekavvvnmyZfe+hvOz5Mk756lwC4JbDDy3EB01BUgmHL7uZBflPffpX3J6R1IoXr9Oha4nY1wEcOmDRU9zPucuvVY6UWlAi1svzRQBHeibbY3rGUO9+B5e+GPaImdw6cyWprCtte1tIM5uKpBIb2Rb/m9JVOpjxjLKncwSMpHa+ASqbvpYGvn7IYnLQMI8vDTfzyqa1ynC1l3ZvcULHJKk92qXOJancoJKYnauC1K+ygQvpxBfKLcT8QRP92iX4rxUZyOYE8x9bRm3CZfaphWz4rYdhJHXrFbD+5yBwHoDjRQV+HEi+HEntTToYip0m96zXm7pfEjMSLnf29WiXOicEldtjMrvbl1VYqtB92EK5WJKqif5pAJ5dMSApJamEQYel4t96NyupeHukG7qR1HRYWkt5EdAfh9MBPHVQCRlJ3Y29DiPE0hcAOCbvkhXVuiSpVwPYdxjdPw8fyKIGm3kwc0JQuaHIiAA9XwZ9F77Q1J7cd/sMgNZumiTNh1LZ2Gpp8zcGhz3GVLWnUwSMpHa68BVOW2e/ORbAp4ag0Pw3n57zse9aUu2dzbIt2MXN2cZSnUgHO0cW2EZv5+CcEFQOY23THErM5qxRDWV94e9CVfcSd841tF6JuKSWpLo5aic9Xi5pn8rzyp4OEejtcO5wiZuZsvxISjLKW7aR1N3LfBmAQ1SR3qRhOg+9hKO3c1AS9tDg8loa36sqllmSNGEicaU9/NSjCVgqCeRUvzl+l+le6RvAuaV63g7goaIxElV6/NvTIQK9Hc4dLnEzU5ZkVHoXXwjgiGGWF414cDcDQuREtDcym/mmh7hGNl9FNc734GGkMmzZVwAcXsUM0g0yRlVrHv7X4r/EJpV1pQ19zdqMmD0UuoN1/FTWM6Iail5j5YykNragjU5Hq9ikqnFuzMdGIRqd1lh2rt4chiRRl+r+3nDgRomVgpmH/7WvmYyTOjdzm8SebVGVzb/V9uQkqcSC5xYFE87fgH/rVXpf295IOl4jqUnhtMYyIfC64TBn89ru1EjqbtC1BMyV7slxSmPw9wB+agCiJxzc2kvvfueAGPLqXgHggKEgna/uElKpwTIxcVIdDPrSGGpuURqMuUmqj6gyIQLTGK8VP5Vr9aihz08AYKittfoubb03G4+R1M2gt44DEdDqNR1I3EjqbiClw5lUc9esagzcOv9aTAcL554hcXVPb+fgOUN8Yc6f9qmUUIU8ktz2tH80NtJL/4cArh8CniijE5KExFmd2UX24lIinNO2Vl8w14qf6jPr6M2OP/smCumgt8M5BBMrUxYCkmD4YnsaSd29XlIK/SMA1x2K96Tm1ipWOnqcLGCrkSQseUtj4qSyP+3h3xtuDvOLVdKQud9RHankiQAYHL+mZw1JqsPjMQDesPL7+jQAr/QsCB24+M2xZyUE5r5cKw3LujEErkGAt1l+EPj/fHw3dmYMOmr4/TMAjjbs9kDgHwDcYvgLpT7XG/7dUzB/6dn/EQBMCvF8gVJvHx7p3T/HM1uTq95wc1uG8TtvMvzHt5XdZOjxI6WxZwN4dGjFQsrFSuNjhy8vmnOk/7H9PQ8Apbb66dnMJRbLRfWMpC6CzypnRkBLbnxxBWmndMthHObdv/eCSPu5ywFQ+sWHuN068/qV0jwzJLm5MhrE7wA4UwyuN4eMWMcpHchem96Ust65x0HHO6fij02rK8+2GtXIrwbwlAHoOXbNsWuj917uGLMvBvCskcHm7jsWoybrGUltclmbmBSN1nlrdVLUMYmPqfvHl3vMacrV6OX9p7TrwGHSlKTy48q95Z617NxKeTGXqGrlpefNAB5RyqRWGoeWJr8MwCkRfet3szapdK5g/rugjNUARCzPNXFf5UVWtmEkNQbRyDq9fKQi4bFqGyIQav9mJHV8kbTDkCxZo/Qmdjtyri6UzfsHpylJtuaovGPHUFK9WEkq5/BVADcfJtOj6jNEuxO61nJf1iaV3oKkSmJP7EgWc3nbPxLAG0cW0nhT6A5PUM7ATgCiNZEcAS1F3SXpMpI6Dr+UPJCc3QPADYbiVwHYL/nKldmgTAThvNIl2frogE2Zo08/qiUkVdYlroxZ3NMj7ZtjVf0OL7kva7sobUFSiZvELKcGxOfdz/4ZIcU5n/a07zebq5HUzaC3jncgcJZwJPhnofL3VZH2hj1mD9q1kaS0kJKa3xXEtCfHKXmRcRLknsmWlAbOtSfUksTeviHyvPkcgDsuOMnHUj0vaHK1qluRVJmelxFKjvOkqU0FgiTEss3e9nwqPKPaMbCjYLNKGRHQwa6n1GAy3WVPYZWmlkDbzlHida5wMvusiIow1Vbtv/tIqs5F31M4JRmCaq6ntLbV6wk3vgcfFlL3pTa5+h2t6Xu8FUnlGkgzCV42mbUrx/NsAC/yNFzTOuXAZdU2DexV4bbOAhCQKurLABw6UcfU/X6A3gbghOGnLw1xHanqvs3wt56Cscu4lp8HcPshmD3D6LinNseVgFdptMhpAE4dfp0b/qh2h58luLFuyvNGq5Rripe6JUnVFyWZJnvp+sr6XJ9/BLCP+KOp+1MiHNCWkdQAkKzIagjEhLiRKhmdMnW1gRfWkf74OZWulED05Dh1pTBzcCYhU5nMClvSpMORBMM5koV2oDUdvYXvkir6udj5MP4agJtFXhhC1yxHOSYfePzQMNOFPiFHJzvalOd+TttonQiEQzLetOJiG9grgm1dTSIgpRSU/pG0Tnlv9iod3AWm9uq/L4APAqA5hIuTSjOJQyZXpP4Cmoxyj1Fqyuc7APYf/r1UdVsTUlLNHEO0pK1zTueVEjF9E4CHJySV0uykpovjlpJUwr9WulSd7Yp992bisul7aCR1U/itc4GAlqKGfvxMkrrnNtJZupyqn6V6tN/VqkG5r6QTTE/hlOQHPoakXgrgsGHbvUYEde/hQKMt9x2Gib4HwAMXTlpLpmlfSeld6c/WJJX4SNMw/neu+KXyUsZ+almj0vdQ0PiMpAbBZIVWQEAeOFMe/XI4lhZ1z8XRDkHyQL1ApI09H8C9V1jXrbvQ6jppe6pDdJG89fAslaR+EcCRA1DvAvCgHkAb5vghAPca/v2SHVmJ5kAiNUi12IrLcyZUoDAHk5CyJPjEztnZv3WwNQ+pO6cMI6HcUFSwzIZz0FtY1kjqQgCtehIEYmxRXcdMc3nE8B92eOzp+SqlqISoR9MImWedGMgzr0ZykOKFW0owUttlppjTWm1Iu+5UEjUt7a/BznfpHkq1XvpSnkOaSmfL24kBXy3iTaeah7UzgoCRVNsaJSDwXmEnOEeKyrGn9LYtAYslY9AhbfRHtEfHqV151nvdO1IayJSeTO0556nVjnLOHH1ltX1zyogQ8gKZSyK4dP6yvjxrtpKkuvHItMd/AID7M+WjSSrbruEikRKDzdoykroZ9NbxgMASKaqR1D230XkAjh/+5CP7vSU+0PZ+Os96r6Yi0o47hmjpy1AvjiTaWSfl97O2+LMlkdTcMY/luelO3K2JeTcEIuVL1g1oNtGkCGibQRILqqlDn16lYRofLeU5E8DjVKHeHKem4ileIpIb9GIqovdJDMHUF8sYohv6fpdUTpKhHOHupETwpB2540vARL5bWxO23OHkPj5ktpK4u3jLJaxF02Mwktr08hY/OX24xOSvlrfcWpwOciyMlm65sFOyL6nm7cFxSs5X2+f2KoWX5MKHSejelB7Pvag+Xy0iGcScVVPYMsIELwB8cqitp/qf87vcR6lsc+f0r8vmTHMsBSGuX7NLXbJaM+oaSZ0BlhVNjoBW08RIZKR0MCRDVfJJFNKgPKTHyEdPjlP6AvR2AA9Ta9WjFF5GNFhCtKTJwNaStLVewY8CuNvQmTYdSTEGeR6Wbpf6hwB+dZj0rwN4RQoAFrShTTFSZqGSaYTlEFP2sWDqbVc1ktr2+pY+O0maYtVnPRIN37pKLMfIR0+OU1rV/1gAZ3VOUjVxXyIBlTnsS5f6pToHpWTet5+W9iOJVulaIRkndck+WoqZrC/PwJR7Ukq4ZX8p+0iJQ1NtGUltajmrmoxWT/8aAIa2mfv0JB0cwybUJusqETrlcgAHzwW7ovIhcXcvBkAbaD6fETFkK5rmrKFK4j43iobu6N0AHjD8sZdsXfKsibHlnVos7ehX8vdZhiGL0YBNYRHzu5REpyT58nIix7XEXCZmfl3WKfkl6HJBOpr0JwBQXeKe2EM/hTS2dtinHITc/GQOe6YEPbD2iY+MP9TWuTdTkVSqfsIuJWm9SJScHW6s1ifkdZO2vqWQP9+4pQarFLW3JvmpxuWzSSUmZpcasqMXljGSuhBAqx6FgD5MTgfw1KiWgH8AcIuh7lcAHB7ZTs3VphyE3Nykkxn/7TK11Dx339hDg6P3ZiqS0tlJktTS7SdT7G8Z0SDnfKVJTi0kNUcA/dg1k7bSsdo53bc8J6iNktmnjEPFrlRgPQM4ECgrlhQBHXbqWACfiuzhCgAHDHW/BeAmke3UXI03+n2GCdDI/zEjk5EkhR9DSq9bfD4C4O7DxHapteUHLad0rASMU8f4lCT1/QBaTym7VsilpTFs19prUoNVEo+QKv8ljoESR0lSv6eyTZVE0Nda+1X7KWlzrTpx62wzBKiKpS0g/5/PUnIg89Hz38dsNrNtOtbkY5dDhySpHG2L73+IV79bqZ7smV8HgKGC+KQglb2R1DNE3OFUamTfiSEJUcmSVHeWLLVtTn1qSol3KrvUXSS1xTM09Zosas8AXgSfVY5AQIedWhpjT6rHUh1KEdParIp0YJj6YEib1O8C2H+zUefrWKv6nwzgT0a660mSKs1iXgjgeQuXoDeSKu15c0rPaiCp8iKY4sKzcCvuVV2aNc1NDjN1cfgXANcRhYxDpV491Z4BnBlga34vBKT0ij/GOky5hqnid2rrHtX9IaGnHFafBXCH4T/476Ma3J8hXv1u2r2kRdXSZV+ih7lboTebVEcepy6Cc3HU5eX+LSW0kx6j1N7ktM+NxVLGNV0qBOEYZLg1SVJbvejH4p6lnpHULLBaoyMI6LBTKWyGepAOjm0oreqf+qi1rt4O9ep3ePaSFlW+d6lIlpTgp3iPSz80nXo7t+RQZrV6OoBXFQiMPHdKTOQg93uKvflFAEcO6/B9Yf/f6kW/qC1nJLWo5Wh6MCQQHwNwWzHLFLZdMt81Scetm0Zxz8mdB+D44U8h5KP1YP6hXv0OxV68+6WjYirJlySpZwp7zRZfPxmNJHe4rT8GQHLK5xQAzGxV2iPfs1Qe9CnnKC+rNOmRoQ5j+pGSVDqp7js00qN5WQx+i+oYSV0En1WegYC2RT0bwKNn1B8r2oMzkG/uWmoY8vH8hoh+0GK4rlCv/t5IqpSgpyIVbwLw8AHI1oP5S8lhCvXxrmNPSgFTrVWCY3aPJmRK1F0236n7ndOevJAv5TnyMvtDANcbBtJyhJQ5WGctu3Txsg7OGm8GAUoimFrOefRzYvcBwPieSx8eGtcdGvmBUMUsbbf0+jqMV4iDgAxe35r9ribtIcSpB0mqxiWF9oLvhrRJLVHlm/L9lXPN7XFfuipdr31uPGLXMWWILHlO8Btz/WFQLV70Y/HOVs9IajZorWGBgHQG4J9TqRzZVo+SVE36Q+2uZLiu8wHcu6FdKokEp/UQAO+cmF8PJFWSnhCTkNAtIdX9rZNUeX7l/mbKEEq57V9D11qXKzHbVM4xjklSW7vox+6HrPVyv3BZB2+NV4GAdpbioFNJc7SUiG0vjRZQA6iSIHC8oSFxWnacikmP24N3v4yPmvJyKPdgiKlJDe/V2BhdqLKlMZ1DMEhtTxnS59wykrSVet5KO9KTALxx7iRF+Y8DOG74b6aTdsljWrvoL4AoX1UjqfmwtZYBSvzoASnTyKWUuvRIUrUUdQ7xaNVxam6UA/duXgjgiOE/LhIevC29u6njozpselL3O23NnHdtyR6S2qESv9EpVelLcNpVl1JohlrjsyTtNuvLuKvSJnWNS0sufKppt8QXoBrwbKA7ESCBpB0qSZV7Ut88pdet6yNUqljr8r0bwAPE4OdIMiRhacme6m0AThgwmaPS7kHdLwkPMTo30caXNtGh5iaJul61GakJmgrxlmpgMsnEnPc7Vf9T7ZROojl+6ai79HIh40ubd//U7kj8u5HUxIBac/+KgFZJM77cPQDwAE75aJvUVKYEKceYqi1pr8Y253r/XiFUVS3ZUzGftgsLM0dq0jpJ1RLmlOd9LzapLwXwzOEFXusCXLrN51oxY5ecm/JysdQLX66HVPebJHXJCgXWTXloBXZpxTpAwGeHOpdQhcCkSRvrpIoaENL/2mWkhIWe+ow5ywM49JGOU/z3MaEVCy6nidixAD4VON7WSapUyaf+oPai7nd7hPGYDwrcV0uLSSl1ad7zNTh2EX+tZVsikZbnLi/ENxgW2OKkLt3pAfWNpAaAZEVmIUA1/xcA3FTUyuVYITMGue6WHEazJrpyYR1nNob0t+g4JSV6c4lY645T0is9tUq+F5Lq7LjX9LRfM+TV3GOs9JSocj7SBn+JqYa8zMqMU/8I4OZzAbTy8xAwkjoPLys9jYBW89MeiBlK5kj8pnu5tk1mupFPSGzMkLZLK6Pte0nG+LGYi2mLjlNLAtVfBuCQYbH570NLW/iF45HrHXOp2dX9aQBOHQq8BMCzFo61xOpSapjS4XNqrhLb0lKj1hDH1eEryeWS9ZORAihRv9HQwZoXl6k90+zvRlKbXdpNJqbV7zQyvz0AEonUjyQYbPtHAO6aweY19bhj2tPEP1YFKA6SNd0AACAASURBVL1UW3Cc0vttrs1gy+r+XEH83f6V6TuZupMpPFt75EU4d6YpiR1tYGkLy6e01Kilp0SVOMpzcwmh/KKI/HGViFazpM3W3pVs8zGSmg3aLhvWQfuX3F53Aejz6m9VmrMk5JTGsLWMUzIG6FxVP7GRtmYx9Ut+ybVdeOqzXqqkU0tpS8FV2obOvQAtmYNcuzXJcciYa0iJ6uaRynFQRlQxSWrILklYJvXBlXBo1lRlCOiP4pcAUNI1VyUdMm3dF1PVUVWbo6+Q8eQssyTklB5Xa45TlGo4J4YYotQySc0VxN/tqR5sUp0pyZywZinOAimtzHXRjx1nyfayvjnJ6C+xQf2l8IXfGJfe2ySpsbtoRj0jqTPAsqKjCFDaRwLkMnGwYAxpCIVYq79bPSy0JGAppi05TsmLCsnqLSIuKS2r+3MF8e+FpEpTktROZ1PnnNzbpZFU+c7Emh1NzT/l7zLGaawDr/zeGElNuToBbRlJDQDJiuxEgLfKcwZHHleQOdOZOz3Xo80KYg+fXONL1e7SkFN6HIyNyugHfC4FcMtUA92gHfmxjCURLZPUXEH8eyGpMprG2ir3kp2TSo/hqo8iuY68pDOO9lyN25sAPHxomLGmDxz+3ZqJ0AbH+HSXRlKnMbISuxHQUs2czlJuJNKQnX9bEl6k1PVNLUXlPK8EsN8wYQaldodtqRiMjWupw5Rrt1V1fypbvF37onV1vyRja9qjEvOSSarUxtQQ7k/7L8RIpqU0VjpOtZpKuajvgZHUopajusGsFbRfA0PjdUmwajgs5y6u/Biksu+Vhy3/fdTcQRVSXjq0LDH1uBDAEcOcWvrg5Azi34sk1Umit5CWlUxSa0iJqo8pbVPKS8ccaaq05WdUlFsPHSw5ewo5SssfhpHU8teo1BHyhvoxEWeS41xD7a6laCQazLzU0pMicL8PjxbipNK85GLhvLDELq5Vdb/8KOd6J1uWpMrL91I78JhzyUhqDGrjdZZqpSQx/zyAnzaSmnaBdrVmJHU9rFvqyWeHmitov8ZNEou1iPGaa0cSThtfXgL4UIrq/r10HPKwpdrKqf6Xtrtm/RcAeG6ij0SrJDVVpp1d69oyST0dwJOHydOGkWYhaz6lOk7J2LtbSJiXrIF8J+b4TGihCOfN1Mt8TJK6ZEUC6xpJDQTKiu2BgPxA8YdvALhbpqD9smOStc8ocrXFRyTXduBH4HwAdxQdLJEU6nFKm9TvAtg/10Qytstx33Bof6lDS4skdQ17VMLfcsYpZ6vMCAm3yriXx5oulaTKvVUbQZMmQjSloso/5NHvE+d9PyOpIdClKWMkNQ2OPbXCm+X7hLqVMQT5Iq8hbdBOWpcDOLgh8HMnQ7hEePTTrvegyrCTZhApSHaLJFXGR81JJJgRiZmR+LSUcUpKC3OZSky9dlubG4yNTxI2as44zloebUIV6scgBTL81vE7ZyR1xVU3kroi2I109SEA98ok6dsFkU7zyLJb2IvlWkYtnaaB/jEzDfynxiadsVi2tvdfjj827JTEqEWSKsOM/Q8AL57aFJG/t5pxShLErbQ0pWackuPaisBHbtc9IiawjVANlQw/xUsfHyOpsasQUa+2j1TEFK1KQgS06iMmnEfscM4A8DhRmbdaqv/neGnG9p27nr7lzzlE54xNBnivjaTqvZci7NjHARw3APg3AO46B8wCy+pwOzlJVqs2qU4tnNIWfO5WkRmnlpq0zO17V3l5Tq159qeYg7YtDT0/ZASQcwH8CMCJw4BqkyanwHH1Noykrg551R1Kux7mgadX/RokkVJUhgGR9mGtSFH5QXqFMJ/gBsklpWAgapcV7IcArl/RbpSmEKnSVH50sKUmDIxUcfeK8PANVZKIVBiNQdIqSXXS+lzvYMgWkxLLUDIV0u7SMlJQ8OvDubW0zTXrS8fRUPLP9+hGwyCpmfiPAE4Y/vvtAB625gR67MtIao+rHjdnHfpnzZu0VoUzDMg9VyLIcWiF1eLH6ExFUHPdzrWU7QsilErYaLcrpceeQtXP2chLV6o2t0MJkEQ+1z5y82uRpEppW04p9NQeeQyANwyFHgvgrKkKK/0u1zyU5K00tKBu5pJUbWJGE4HnDaYC7JC+GfcP6tkKRSNgJDUauu4qaqK4VhYWTY4JfKg9UcmLRPU1b+JOssmx0uaJxDWHdPo8AMcLQGoiZZJMplz/lmxS9Qc1t6ahRZJagqqf+1uatpR01slLUEnjCj3nZRiqkPdDmwjQ2YraiucPHa4pqAmdY3PljKQ2t6RZJqRjd+b0GtYT0LaotcXn8y2Itq9kGUq+eABS3Zj6oSTy0yrkVElqxF3z9YWA4d9SPC2RVGnHSGxyXyJbJKklqPpLJqnyfamRpH4YwD2GgyPEnMMXzq017UuKczRrG0ZSs8LbROMkOO9RWZ3WUoX5bFFrIVdji+9T8TMl589mIqgch5aC1xK6i+v/AQB3EmCm3HstkVQ5lzUucq2RVEnycxP8qQ9DqTapLZHUvwBAs4pdj9zjTjBjJHVq9yb+3UhqYkAbbE5neFpTxaG93ucEYS5xKXwElV7E/HuuOLM1h+7ScXFDpB9z1r0VkqrVkiGqzDk4+cq2RlKdKntNLdGuiyyzzvEp6VIu35eUl8WlezG0vtyzIeZOJLInDY278kZSQ9FOVM5IaiIgG2yGElQelPwAuueTg6F4DptJH4TShoi/16hicvMiET0bwA3ERElQqVLKoeJ33dQaussn/T0isb1uKyRVxy4ODVS+5NhqiaRKx7wSHIJKlaS6TFzcNzVyBykt51xItHc9MvoHk2Q8vkFnyyVnwCp1a9xoqwDTeSc6qxThWINQSdj/GMDTFaFLlcN+7eX14UmJDQ/NnASVeH2wwtBdvrixOSRKa3rD59pz2m4utbR5bNxyjdaQ3ObCj+0+DcArAVwG4NCcHQW2XWqcVOkdXyN30O/K1GVOXv74LXqVkdTAHZywWI0bLeH0rSkPAnyRKUGlmtg9uVXSehgkVyRxh4sfSpBwxGwY7XTGNnLboLpxanV5jixWMZjsquOLG5vLxORtIubhmwE8IvVkMrfHd5TaDXl547/5vuZ+TgNw6tBJzsxWuefB9p2EMNc+mzuHUiWpjqSuYfM8F7OQ8r6QUtSmjD2SlDstnqn7Q5BOWMZIakIwG2iKBJVxO+VHjwcSD82cEj8NnVZf1kCufMtPw/zfUXgyODSJa248dWxRjq90ou+TOOckDu8VMQ+ZTcYF6a7lVdb24mtJUYnPMwG8dADqFAAvqwU0NU75npTyPSyRpEopZAl2u7HbLTQMlSa0TuoqL/5rvm+x862+XikvZfVANjABHtb/F8BhYi5rqKQ1dFr6x99rs0XlAcdYelSJyocElR+gXbf3VFuJ0nD25Z4t0zyGzMkXRSInQeWYpF1lbR8cbRLB9SXJX8tevFSVdMhek2XcHihp/UskqTWnRJXrLVMhvwbAU0Y2jHZGdFzJSOrcN2xheSOpCwFsqLo0iue0GLeTH6K1Pnrs00dQc2fOSb2EPMyfoaSn7IMSaf62BkElSf4MgFuIyeWw6UyJnV77EO/bpf3LPmvaZ9qEhJcfSrpyRYjw4dwCSXWJQvgd5CVpzbNu196V2Jby3jLxyEOHQZeUBWvuGSC/c+8C8KCRBqTkWJo3tOQwOBe7TcobSd0E9uI61Z7UDPx+n5UPbZ1ViCAx1/wxK6jGUyzIcwA8WTkpuXYZ6/PkFeehA7vTXELa96aYb8o2tEPDpQCOWmH/SZJakwrzswDuIBZgCzOOFhyn3HtSkhSVy+ocufjvLdbW925Lcldj+Ck3p9CLqTxD5dlgJDXlyR/QlpHUAJAaL+LLfrR2MGup3nJwU33Jg2INyWPsElMSQ/LJD7Yv8gAlXDwU+b81pTTSa72kD90YzlqKv5Z5hy9Yd+xeWKuevlBuRbBa+FjTLpzvcElSVO4jae/Li++frLW5RvrR9pk184bQi6ksJ82OWricbbyd5nVf82abN1Mr7UPA5yi1xc39AgBHiwF+d8gGQrJV4vPgQdrxkJHBkZxSMsyDLreDlB6C/qBwLKV9hOWYNelaU6J5FoBHD4P5GwB3LXGziTHpyBtrSZx9sNROUt3FOLfdc8yWkoKDtS5su8Y5JlWMmdvWdaTGbtdZw9/uOwyW/gUvGP4tSeoW38qt8Vu9fyOpq0NeTIc+R6m17fLuPTgY/ReFSokvP8nfiYOzzVi81qsBMJTRb25ATh2ELwbwLIHnGradsZvaF+5sTSm+jCJRQ1idrSTOLZJUYsn3uMQLXGn2vlIzUyKpn3P+hJJUGTlDfo+eBIAOV3xKkHLPmXuVZY2kVrlsiwfNg/l9SkW9tqOUVkm7SZVGFogVHaH44ZCxY914KankXNz/Fi/Owga0vWIJkhjflHyXpLWDwss9uJXaPHS5tcR568uHHE+Jl8pduDpJZamES5o/bY2t1szUbI/KPRFDUuUZWpqUO/T8qLackdRqly564L5g6fxY8zBcy27yEgC39MyAan6q0Le2Q+XBTJx+DsADR5CmMxIDmjO/81q4TS26tu0ljjxgS3tKuCQREymZLJmkam/+tcNN+fZPzbZ5PO+4B0k4Snl3JcYlkVQp1S09jF3IOUfhDNedzy4TH5pp3WYoJ4l5aVLukDlXXcZIatXLN2vwJF6vGMiXrLi2NEFm+ZHjoESSB8BWdqj8aN1vOMD4kfBJTTleHtT8QG81zl2LXpI6eGycPhX/xwD84gYmEjKjzNrvwZyXt0TpeK0klWfM7wM4G8CvzFmEFctKkrr1vqxJ2xCyRB8FcLehIM+du49UkmeDTJ9aYgzbkHlXW8ZIarVLN2vgJAZ/CuC2otYWZEsHSOZwrho+GI+fNaPlhTmWnx2M4xnmaszO1PVEcwg6Qm0t5d1F/iglcE9pZhMcFzFnRjP+vxzn2hnN2LfOyFWqWYRW829NWty6PRvAi4b/qCUtqouLyv/fWo2+6wSTKuWt11uStdpV/cQ8NK2pnLfkSSXGsF3+NSy4BSOpBS9OgqHxMKY9JT908qFqk39bW9X1DQA3EQP5waBOz038iMOxg5SUHwCSpDFJqcSJedFfW5hKf2xb6BSZpX2EiTfTkPJD554t7Sp16DUpLUnw6iVpQqeJLSk9cI1pUSVBKXG93aYphaTKcVDTFXJmJtn4GRuR5+SYo/BYIH8OyySpGRfH17SR1JUBX7E7SoootXL2N65r2ny+c8VxuK40QeXfX6I80VMMix/2g4bDhBLSg5XkblcflC7zEKOKi/+/NomPnT8zwTAjjHtKlKKWEt/TYSQJy5UADogFP2O9ks03arPNk5LztaOYzN0ipZBU2tyfOgx+ywvlXPx2lZckdSwElcRfl6lt36fEbpO2jKRuAnv2Tn3OUSRgfPnWjtvJyX4LACUX8qEU9dCFRJDzoYSUHyCS01AJqSRzlE6dURkp1RtIS1FLU11rM4/zhxSLW14CpAPFhcoUJvsLGtCBtPlk8dJIQm3xIuU7snYUiYDl3qNIKST1E0Lz8XQAr5o7kQLLh5BUube1uYX8rZSUtQXCnG5IRlLTYVlCSyQDDDxMlYR8KFnbypPVR1A5thA7NpJPelhy7FQ18X+cIyMD3HQm4FRXUTLF//GgqklSumuqmsxQovqwmdjkLi4/DFwHruEWlyU5z5I9+33e/FtdMMf2Rk2OU/qStGYs3ph3qxSS2po9KtcihKTK+MmnAHiZWESTpMbs6AV1jKQuAK+gqrsyIG0pgRkjqAzb9JeDBJRkgYSFklZnN0qSdSCA6y/A+NMAvjrYk/Jg2poULZjKaFWSeNrNOluxUgigHLAm0Vs7grixlerZz7WkpPmOAsQSJTbSfKN0yaT0UF8zo1nsOy9J6lbYamLfClcIcZySF1itlTKb1NhdHVmvlY0XOf1qq/EAoYSR/8+bnc8znep9/pbbKWkMRKpyaRuqH6r5l5DPsf748WlNSjq1QeWBy7KlxfrUEsFSnC+0Z39JJFDmDOealkLq9V6sJS2qJlslrfXY+10CSZVkrEQb96mzcex3eWHxCXB08gLtYGckNRb5yHpGUvcEjh8vpr50kql/AUC7nO8ofEkA15DMOXU3X4xQJyAeKPzQkcBs9TCn+GEZO78IAEkpY65yHUhOe3u0d3oJAd7lGvjCTZVCEDR2pdjw6mQMJXnz10pSJSmpJRj9YwC8YQB8q9Sb8hKypTYu9bn+JgAPHxplCutHqA7kO+i7VFsIqtQrMtFe7ySVZPTkgZQywC893+c8jPF5MYBbDJUcuaUUkeTphsP/SKp8jyO6rM+6JHfS9nLOWErJgOSLhTpnHq4sLwZUe354wNKR0S2dbWLmkaMO98g5KnJDSSGnuAfoQX24mHxJUl4tgS7hHJQxPB1sJcelrEGSqiXmW6nO554BkihtdYGS5L5Uaf5cXFmeNvuMhsLnXAAnqEakJsNnGmKS1BjUF9Qp4XBeMPzFVeWtaHFjKzcgHYH40S1Fmqg/DGOw/BDA9YYfSfZJ0GmwznnwgFxDUr3ykiXrrmRnKV9kia3i8o4BLj37v5ZZ6h+66DrcVOnSqxocp84C8OhhAUoxNQnZD/ICsBVJleZaW40hBKu5ZaYuV/I99JFzKeV+LADuMXsyItA7SdXqtYxQRzdNFRVz3X8ZwLuFh3p0gytU5G2UIUscCZVdkpy+cjBJMCI6fzG0xK0UZylKT5l2V8flZfrJpy0MNTYfpd01ZF7uEiS8+tJRg1q69BBU2rawFikqd64kUltI01t1miK2UlLquwhKh0ofOZemQi2R99RnbLL2eiepBNLF1uShxniZDP4un6sBfE84AZEU8CPHv+07qKNZxj1sx5GvGwDYDwDV/b5sHfybU1+TvNEj3f0326idxFGqeisA3wZwnWFutc8p2csX2ZB2rNmaZI1lNeP0SpOgckylqYD50aPphjwfavj4lR6KR74n3xzi4NZiKiTDJG2RGUtiV3rig7nHqLwAaHW+tlX38SNZpiQTq7k4VFPeSOreS8WPmPOWp+i/loOtmk1nA41GgJJ/GvuT8PPZWoo6Jj3luChp29J5bwxkEkIZR3hLQshzhh9Kabtbi/0fpePUiPApLdB7zVJU4ikl/Vt8o2V2wNaI2C6SKrUDYxENjKRGf77iKm7xAsSN1GoZAn0jQEJDgkVi6J4tVZg87J8NYB+1LFSh8bAv9XL3dZEIgtE7rrvhttKZwmqSWj0TwEsH7LbyQB9bOikJrMF0Qs5DEuwtYrpqE7jSEx/MfX0lEaUQiuYU7pGe/2M24aUkWpg772rLG0mtduls4J0hoAkNnX/uvwEGJMtnemxP+UElcd0qLm8IFFrV/x4ADwypmKGMjjBAx8F7VWTiIz/WpYQW4zLpBBe1SQIfBYB23Hy22J9yX9ZG8ENe013xXy8AcPTQyOsAPN7ToJHUEJQTljGSmhBMa8oQyISAJjT8eGyRJpN2iEy7q5NH/BGA5xUsPXXLch6A48UabaVa90UV2cJBZsl2lR/7LSX6eg41S1E5F2onXjRBlJas2666+hK3tb17jnlKkqkl1TRTutHQ6VjabonRVudHDlyKbdNIarFLYwMzBK5BQNpQOUjWtqPkwUzPfWnLybGQLPNvpYQ/m/oA0zFxf1FoC2Loc5QqieSFvnaSpJbysa4xu9Qukr22FFifNVu8H6H7L7ac3LeapErP/jHspTlGTeY5sXhtXs9I6uZLYAMwBEYR8Enc1iQ0znOf0h1GspBPbVIWqcrjPC73RPLIvRV9jlK14egwKlHtKU1itrDnTLF/5BzWNqOQsVFbSoUq10XaUn8EwD2HH+dE/XBkttY9lmKfrtaGkdTVoLaODIFZCFAqRJu0Q0StNSVWJCGUnkpHLQ6lBttTDfTpAOjcI5+1pVTsW4cPK93JbNeGlSS1hMQD2uGnVingVJzOWYfIjML6QrzF+zFjuNFFXwDguUNt2v66ZA86/NQuYYAj80ZSo5chvKKR1HCsrKQhsBYCvrSna0ncxlT7zApGu9PXVmB7KteJ5IU2vQeJP24hJdIfQZoe3KcyLMckUr4c6Gu9K+yH78snha30Wu9K6jlqad6a32cZ9qqm7Fxz10BeFCUR1+/nLpMqk6TORX1B+TVfggXDtKqGQFcIaEcpX47p1IDwQ0+nKIZo0U/NEj/pDMF5XQHgmJW96DWJ4jhqlfS5vUHvZ37k+ayxP3ftd4bCohqXT80e6acBOFVMdK3vs5ZCr6mxSX2OTbUn055Kcwqd9S2EpJpN6hTaCX5f6yVIMFRrwhDoAgGtdqNKiR+RXHFHKb0hOWW/+mHfPLxrcIzybQ5N9llmbTs/mkswZJc0m2iBBEhs17ST1uusA/evvb4pDyWmvX7A0ODXAByWsvEdbX1CxAvlpY5nQq7zZqUpebvRkmoZA1Y7je3iRk6SWoKZy5Z4rtK3kdRVYLZODIEgBEhG/wrA9UTpXBI39vUMT7xTdk1ySrXYW4JGXWYhfpCo1nchZTjKNT8qJE8nA/g9lfCgFTs26eCzpf0i9+iJwxZ8O4CHlbkdg0YlVe5rmSxo4kb77acGjba+QrsySkkJ6y5zIAtBtfK6G0ldGXDrzhAYQYAHKCWaMod7aokbD1gSJ/Yl+3FD+gKAR1YsOZXQaskI1fxMP5pbQkSMSf4pmdYY12w2obetdPDJdZGaOixkyKmtUwRPjXXqd2mywLJrEX+tbTgWwKemBlvp7/ISoKX/V4vL5K5EKdI04iQAb6wUi2qGbSS1mqWygTaMgC8W6seGbEgpSNW9h+wpPpU+YaXkgMS15GxRc5dfhtNh3dwq6V02vez/jMFuMsV6zsUidXntZLLFd0Tb+eZe39QYyvYY4o3/O1D8cY10pDo7VytSft9a8fItCaXEV9vkngLgZSMLLsuusUY5910VbW9xuFQBjA3SEFgJAZLDlwOQ7yJJIw9D3vyXPLtU+pQ8UVVKSUpL5JR4/TGApwvgcjvTUKLHcF0kb/qp3a7Xt/92qU2X7Nc5daWaf00zjjljDCnru6B+ZZD6h9RfUkZLUdeS3i4Zc2xdOdd/BHBz0ZA0XZmyyZXrZSQ1djVm1DOSOgMsK2oIJEaAkgyqlmSaUZIaSjxjCSolTLTR42Gq05dy+CTAzt60BameXhISRmIobVFTm03IPklMGYLpYDUQEifiXKvT2a6tLgniWraTcjyaJHMNatzLfFcvVmYha2Vx09LwLcKyJT5OdzY3purXWcqmLjxy7xt/WmEFDeQVQLYuDIERBHTYk4sAHBf5wZ2yN70MwJMqd4aa2kg+0n8pgKMiMY3pj2FpeEFokZw6PKQpxdre9FTrU/PAZ0rqNbV+W/+uI3l8F8BDVtBskBx/HMCRAoC113FN7DURlTbU7wXAcFPuufHEWeEcrFo2jVhzbSb7MpI6CZEVMASyISA9StnJXAcUHr7MmPJzAI4eGSUlMyRNVHe1/PDDS6m0zpC1K97hUjykVIVtMYPN0zIR4qVjTVV/y4DzmtTVrm6Vamauz1pSaW1iMCU9TLV3tmpHzlea/ui9HIK/cxi0GKkrraaR1JWAtm4MAYWATM/Hn6bUbTxQ7zeQMBIxn/2j7MKRUxKpGlWhczeMLyZqbjU/SbF7cseznYtHrvKPGsg425e5z3P159rVBPW+AD6Yu9OM7fP9fQeA/UQfa0gzaafOuL0u8sTlAI5o/IyQqn5JyHWaYp6xPDfHHimRzXm2ZNx29TVtJLW+NbMR140AU2E+ReSMdrNx3sn8ePAwZCgYHpoPHZwo9gmcNm/4PHxbc4baNX3tncuyOSUd2qyg9vBHgVvrmmKvHvYv//2B4eI0p35MWS35q93Bx2eWQrKo7ZpjsNpVh+fKOcpWvXYspzDSXv3uIqCjQ4RIk+U5k1NDMzWnrn43ktrVcttkN0aAgbKf7BnDlQC+CeCmAG4YMUZ+4OjRTlu9HqSmEiLfBz8nQfVlkKo5/NHc7SYl1msQHG233YIES5v5cA1yY+nbtyHEbO7+KK28NMn5jgjzpS8+IaYjUvIaUr40LKocj5HUKpfNBl0ZAiQxJKc/nXDcNA+gtJSkoWUnnSnItMouZXxZ3TcJ00tUBqmchHhq7lv8Lu0oc6un9dq2QKp00H6uYW4nHJoWEDsms3BPD/t2zOZUX2xDsXBmA7lD2m3xXhfbp5HUYpfGBlYxAjwEKRl54OBZLoN0x0yLEoDzAZw3ENOeSamWojKEj3tyqd1pD8ksUtopix83/taT9Fpmmsqp8tRORS1gzXOBdrS3Ens2VUzksXOF+5MxfGX2s5Yyn+06T/UectJPXgpo0+yeEKmoJLwhDlYx57zV8SBgJNW2hSGQFgF+DKh+j31+AOCTAP56kJCSkMbGTI0dQy31tLNUyo/HVLzZHjz5fftAktSQj/vcvUTc6dhD+z/35JY0zh1jbHm9XxlU/p6Z3m/iSHKqs8z1sm8ZZeOVnj2kzUdCTXVkvblRWGL3i9VTWW4MEEPAEFiOgPZCnmrx+4O3NMko/9eTw9MUNrt+185SKaWodFZ7oUdyyvGwH36wWg/p5cNeX8BSCzl8BDVUFbtkL61RV8fqZJ+5yA6lfnSQ0pL/XiSo2imKWLtYqMTFSZWZ2euYQE2IsyM2Vf8ab4voI/Uhs/LwrTtDoDgEfB8j3yB/COB3hximxU2i8AH5VJgpHGr48Xr+QEJ9EPAjT4eLXiXbMksRybpUIS/dMj6C2oINqsNFx9TNNTefBz/HECoxXLqOJdTXtsy8+NN+mhoqmYUv1KbaVP0brqqR1A3Bt66bRUDbQsmJOslpqykzcy+qL9c545Xef0HHjpyS/GriRTJGqSnXq1dy6qBlxrLXDP+RMkaqj6CmNN1YsDWSVPWFSMthKsFLxNsBHCBGvVaa1SRAJWhEp3t1Emu+wwzr5545Enp58pJbdgAAESxJREFU5uSSfieYeptNGEltc11tVtsjwNv37QFcD8CnhUqpJyeb1KvwbAAvUo3yI8wPUwyBZL2TPXZ77MKF9XpdZNup515Ce1JC9S4AD0owKBJUShmZqMI9KaTiCYaWpAnuMaliZqM55qdtLdkPbXl58Yp5N5JMfoNGZOB+ds/LDv9G+1z38MygxDn0LOb5zdTKUwlXNphu+10aSW1/jW2GhkALCPjszGII6pRDFD/sJGMkTvbsiYCM75kqrqdWg7ekltZqZ6JJlTOl/qEEKWQP+uzgmWjhxMT9hIxlyzLcO4wVLcnos4YEFFJDMicqhTTfeiKA1245wR77NpLa46rbnA2B+hDQH+KLABw34yNMyTbtTal69dlS0kSDHzkL7+XfG88bJIDu16VqT5+Kn+vDdMEtPD6zlJhL1RQWPvV2S6YSU/OXv+skCbxIPXdI++rKzZViu4sGzX54hqS8XMyZW7dljaR2u/Q2cUOgKgS0xC1UGuLIqQ7F4yZPBxazD57eCl8GcOuhGO2q952usrOEDseUy5Fo4TCjqvMi9GYA1xG1c9iG+pyk5pKwqAkWWEnb/fLSyT3FcGbumWOHyjq8SDEOM/9/bt0CIapzSEZS61w3G7Uh0BsClGAcNEw6JAzMvQE8fsTelFIRElMSpZ7s9WL3jCYA7xkSVcS2pwlqSwTAZ5aSIxEB+2F2tduKRehVgkoItBSVwfr/XHjz0670PjMlodJcI/RSHPtOWL0RBIyk2tYwBAyB0hF4zhC31I1zl9SNklM6Schg8K4eyS3VsJTKmtoufNV1tIrQ0D2+HrSdJp1RqLJuZT20WUoMOQpZGV/KWDpPtYJjCAaujE5/yux8TIrCfcWHl1L+e44pjzSjaCWZxBxMiylrJLWYpbCBGAKGgAcBqjRJkpwUlUV8JGksww7Lkwg5yamBPA8BTQBCpNi+Hnzrkzsl6LyZpimtpcRLbXd9o9J2qDmcsdKgsU4r2v6X9upHiK7nOvlpaXiONVwHmQZ6MZLawCLaFAyBRhGgNJQ2ZdLR6aMA7iHmy98YRoofKu0QddngDHVWo/isMa2/AHCS6CjG5tEn3c7hRLQGHlN9yBBIsYR+qo+xnPRT9Vr9XWJOe+l9xERjokVI+/eeTSiK2C9GUotYBhuEIWAIKASouvx95Xyi1XYksfQI1+kf2VQMmbJF2BuBzwO4nfjzjWeqlCn1Y774m4s2Wo3fKZMdcLo5nMG0fXDv+/zBAN4x8uLGRIuQUmqLi1rAiWgktYBFsCEYAobAHgg8cwgdcyOFi1PbPRLArwCgc5R+WiVAW2wRSqaZ1MA9cxymxmyDKZmi1Ls120lf0P4ltru+9dbe/HOD0m+xh3L3+W4AD/B0EkPeud8ZX/ZOQ3vmLJV79QLaN5IaAJIVMQQMgVUQoFSEBJUfB/lcBeBxAG4GgBJWmX/blXNOUbQJtCcNAjFSu122wacBYNaw1h5fTFTaid4l4US553lJkN78c20tEw6niKZ4WX2jZySxuEinNzpf+S7BRUy8p0EYSe1ptW2uhkCZCJAM/R6An/IMj3al9JDWxFWSUzpF8X/2pEVAp9rcJRkkOX3GICXVo8gRIzTtTONao2STNtPa3CSHva22Q+3dVlJfoLiC3x6ybBGrmEfatpqzVAyCGeoYSc0AqjVpCBgCkwjQfu/uAB6hPPdlxR8DGDujKF1lFiSmKWxNdTwJ3koFtCr1J0fiylLKR7LmQv644bl4tLxAtLZGnCsD9h+s1iIm3NHUcmqCSinfQxvEdAoH9zuxfxuAA0WFbwE4cgEm0ha1pbi9oZgWW85IarFLYwMzBJpFgFlcfCr7kAlTSkWVfovEJ2T+a5YJyTJFFSmletJ+mESNa9Si7Snxp8nCqZ7LVeqg/ZROn6PIP7Gl5LbXJBRj0uuxC1To+yI9+lPbEoeOwcp5EDCSatvCEDAEciPAjy3DGNFGj/+/f0SHJAAkPvyY2JMfAR0f1ec0pQPKc1RcJ5LTOYHT888mXQ8++9OvAPilIZ5vqp58ZKx3gspz5F2DBkbivFTyKR0EibEOZZdqTa2dCASMpEaAZlUMAUMgGAEe+Bd61KKhDTBO5292LDkKxSl1ufMAHC8alfEmx5yj/mgwwWhNte9goNSY2cwkickRTYL2lv8LwAEC/1bteufsW20j7eoulaJKh6nebX3nrMcqZY2krgKzdWIIdIkAP+aUMsmPbQgQlGZQYtprmscQjHKW4bpdoiTejgjwN9qfyrSzXC9+6FuWclOySY99+VwK4KgFdpC+NdQZq1gmtRlBzr2Ts23p2OT6OR3AUxd2ag5TCwHMWd1Iak50rW1DoG8ErphJUEl2qE7lh7pVaVwNO0KrtHnROHyQIGobSc6nh3iSNF84Viwe9yqJeqwnud4HvuxqLHPGEJat9/fBd0ngGtAsZQk2MkpArgxhNbzzxY7RSGqxS2MDMwSqRkDnF981GX5sKDW1GKfbLzklpXRskyptxp0kSfOFW+qBoPpsb2OCxftWd8x0wt6JPdHy2QIvXQNifwGAWw1dxaRQ3f6NbXwERlIbX2CbniGwEQLa8WZsGEwdyQ9Qr97KGy3PaLeU3DFxgnsoXWLAdH7AZU70HLFAS8OC46GkjaGmriMGt9RRxzVF6SBtXHXorhx2riViGzomksnPqdS6KbJtycsHM6vpcGKh47NyGREwkpoRXGvaEOgcAZ99nYOkdS/wWpf+q4oM/AOAW6rJ9EKifI5SzOdOUrlExezIr885yhJT7P3mMNHHKerPSyX42nwgNktVre95NeM2klrNUtlADYEqEaAUhM4lNx4yR7mP+9KPfJVgFDxopqSlZ7NMu+kb7tkAnpaApBUMxTVD83mSXwTgZxNI/cdCd7FP0yjsuTN4fnwdwPXFnynZZhKQ2Idt0gnOxWqmNocXEnsKRMBIaoGLYkMyBAwBQ2BFBJh2lheJqacXmz2SxZerbGcpzBt6Dd01ta92/a4JfYpYsTJwf4r2lszP6k4gYCTVtoghYAgYAv0i8A0AN5mYPgkaJU2pPNlLRpuqfEYwkI5jKQjqWOrYXoh/zJoTs88rW+ilzlKa9Br+MSuzYh0jqSuCbV0ZAoaAIVAQAoyFqu1N9fBoAtBqelM9V5IiqoElQWX4rYctzKB1HwB/OKQzlX2aHeT4y8A1+CCAo0WRpc5SOkKAqfkLOozGhmIktYJFsiEaAoaAIZAYAZllx9c0CQHV3i0H6NfzpqT4fuKPVAVTshqb4pVE6xkDyZd99Yjt3O37AgDPVZV+YcF+lPFQ2WwqB7i587LyMxEwkjoTMCtuCBgChkADCJCA3WhkHgz3Q0eqnpx4fKRoiSqYpIjhpZxzjoOakRFI/mOJbwNbb3IK3HvvUKXePki0Jyt7CtCTnyYcbi2MoMaguFEdI6kbAW/dGgKGgCGwIgL8UDNsz74ATlUqbTmMXsJLyTkTG0pRDxJ/jI2FSumpLysXm+4lMsKSba0lnmxriXMT1+N8AHccBrWkrSXzsrqRCBhJjQTOqhkChoAhUAEC/Eh/HMCRAWMlQSVJ6Ck8GKVr71MST4aaOi4CBy2xc5CTGNG8oifTiYDttlcRX1YpFloi0daOUj/ZmYYgZh2KqmMktajlsMEYAoaAIZAUgUsBHBbQIp1IqIbuiaASllR2qCT3Ojg/ySlJEsmXPbsRGCOodFw7JnJfaqnsYwGcZQtRFwJGUutaLxutIWAIGAKhCOisOr563wFwQifhpfT8fUH1YzzufTib7WnoLr1Wen/miAlKbGYpHamBUSp4CbOnMgSMpFa2YDZcQ8AQMAQCEeCH+uIdZWmrR+lSTw5SDg4SI2Yuuo7AJ4bI+MJWfQDAiZHSv8ClbabYmIkEJ5jKLtgcpSreLkZSK148G7ohYAgYAhMI/BmAk0WZbwF44WAf2SM5JRQkRpTc8f/dQ8knw03NeXz2rLHEak6/rZQl3rwoHDwyoTtHRkHQpgOx0thWcK56HkZSq14+G7whYAgYApMI0HmKaU+vAPCpydJtF9B52znbjwF44EzJJwkWia4MMZUiM1Xb6P/b7HyZveTcY6TarM926QjnnqUZqnpZj2LnaSS12KWxgRkChoAhYAgkRkA7Ss0lliSlDNCv7RvZDk0ILP7p9IJRgk0iKTN7yVo0Q3nozEsD63NtKBE/fGjM1PzTa1F8CSOpxS+RDdAQMAQMAUMgAQI+R6lQlTKJFckpQ0npx5yk5i0OifyxI1XmXhpkMwzxRVtg91i4qXnrUmRpI6lFLosNyhAwBAwBQyAhAlQD/28A1xVthnjyP2GI0+mCweshvQ7Ab0RI/RJOraqmtI20HDxDdlEaTWn33Een+X06gFfNbcTKl4eAkdTy1sRGZAgYAoaAIZAOAaqVqV6WjlK7bBWd1JSEaUwlTVUyVf4xhCrdzOpqSduLytF/DcDPRZpL6BBgMU5wdSHZ0WiNpHa02DZVQ8AQMAQ6RECr+X02jySjVBWTeEoyqyV9VCmzPbM9nb+RrgSwn6caA/Y/LBJTEl+uiUxpG2rCMX8GVmN1BIykrg65dWgIGAKGgCGwEgI6jqnP5vE5AJ4M4FYjY/oegJcCeLmp9aNX7esAbuqpfTWAey4gqDrCgnnzRy9RmRWNpJa5LjYqQ8AQMAQMgeUIaCmqzAO/K9MRe6ZKn/VpR2lPPAK7Mp/Fpir1rV1MKLH4WVnNVRAwkroKzNaJIWAIGAKGwMoI6KxSlKKSMFG1/4rBScc3JAbkZ0B4U+mnWbCxzGcvAfCsiC7oJMX1k/bCXDOaavSaoCICxjqqGEmtY51slIaAIWAIGALhCPhicVKKesAO1f65AH7ViE44yDNKSq/+HwB40XARmNHENUVJRElQ5UNHKRJXI6hz0aygvJHUChbJhmgIGAKGgCEQjIAvm9HnABw24q1PtT5JjklOgyGOKugkn/8UUZt1aX9K6bh8uHZjjm4R3ViV0hAwklraith4DAFDwBAwBGIRoKTtZSoe6vcB7ONpkOp/Svio2renXARIQv8cwJ3UEKni5+UihvSWO1sb2R4IGEm1DWEIGAKGgCHQAgI+W8WxedHJ5kkmPS122Sk5PXkgoVpSyqD/vFjQqc2exhEwktr4Atv0DAFDwBDoAAGqgc8JmCcJDsmNSU8DwNqoCNfyDAAHe/q3y8VGi7JVt0ZSt0Le+jUEDAFDwBBYisCDAJy2Ixe8bJ8ONjQHMNvTpajnq+9zjHK90fGN5hmm3s+Hf3EtG0ktbklsQIaAIWAIGAITCFAd/B4Adw1AihmNfslSmAYgtW0RH0H9FoDfGLJKGTnddn026d1I6iawW6eGgCFgCBgCCxD4MoBbT9Snat85RhnBWQD2ClV9ERkstNQKwJfehZHU0lfIxmcIGAKGgCEgEdiVwYjl6M3/4sH21MhpuXuHQf4pEf+ZIe3sfmKoJKi0TbX1K3f9VhmZkdRVYLZODAFDwBAwBBIhMJbB6EODw81bjNwkQjpfM1yjE0eaZ+xTElQLzp8P/2paNpJazVLZQA0BQ8AQMAQGBGQGI/6JdqeHGzpVIDB2yeDgLwTwCHNuq2IdVxmkkdRVYLZODAFDwBAwBBIjQFUxiem3TeqWGNn8zVGNf5DqxmxQ8+NeXQ9GUqtbMhuwIWAIGAKGgCFQNQJMvEBvfj43BHA6gFdUPSMbfBYEjKRmgdUaNQQMAUPAEDAEDAFDwBBYgoCR1CXoWV1DwBAwBAwBQ8AQMAQMgSwIGEnNAqs1aggYAoaAIWAIGAKGgCGwBAEjqUvQs7qGgCFgCBgChoAhYAgYAlkQMJKaBVZr1BAwBAwBQ8AQMAQMAUNgCQJGUpegZ3UNAUPAEDAEDAFDwBAwBLIg8P8B48hP42lVITQAAAAASUVORK5CYII=', TRUE);
+
+    // Check invalid when PNG is not submitted.
+    $this->assertSignature('not a png', FALSE);
+
+    // Check invalid when PNG has color.
+    $image = file_get_contents(drupal_get_path('module', 'webform') . '/tests/files/sample.png');
+    $this->assertSignature('data:image/png;base64,' . base64_encode($image), FALSE);
+
+    /**************************************************************************/
+    // Delete.
+    /**************************************************************************/
+
     // Check deleting the submission deletes submission's signature directory.
     $webform_submission->delete();
     $this->assertTrue(file_exists("$signature_directory"));
     $this->assertFalse(file_exists("$signature_directory/$sid"));
-    $this->assertEqual(count(file_scan_directory($signature_directory, '/^signature-.*\.png$/')), 0);
+    $this->assertEqual(count(file_scan_directory($signature_directory, '/^signature-.*\.png$/')), 1);
 
     // Check deleting the webform deletes webform's signature directory.
     $webform->delete();
     $this->assertFalse(file_exists("$signature_directory"));
   }
 
+  /**
+   * Assert valid or invalid signature.
+   *
+   * @param string $value
+   *   Signature value.
+   * @param bool $is_valid
+   *   Is Signature valid.
+   */
+  protected function assertSignature($value, $is_valid = TRUE) {
+    // Must manually set hidden values because ::submitForm only set visible
+    // element values and ignores hidden elements.
+    // @see \Drupal\Tests\UiHelperTrait::submitForm
+    $this->drupalGet('/webform/test_element_signature');
+    $field = $this->assertSession()->hiddenFieldExists('signature');
+    $field->setValue($value);
+    $this->submitForm([], t('Submit'));
+    if ($is_valid) {
+      $this->assertNoRaw('signature contains an invalid signature.');
+    }
+    else {
+      $this->assertRaw('signature contains an invalid signature.');
+    }
+  }
+
 }
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementSubmissionViewsReplaceTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementSubmissionViewsReplaceTest.php
index f4b511d244..1e5cb5034c 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementSubmissionViewsReplaceTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementSubmissionViewsReplaceTest.php
@@ -46,9 +46,7 @@ public function testSubmissionViewsReplace() {
     - entity.webform.results_submissions
   node_routes:
     - entity.node.webform.results_submissions
-webform_submission_views_replace:
-  webform_routes: {  }
-  node_routes: {  }");
+webform_submission_views_replace: {  }");
 
     // Clear default_submission_views_replace.
     \Drupal::configFactory()
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementTableTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementTableTest.php
index 51c5288e91..f766d12107 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementTableTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementTableTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\webform\Functional\Element;
 
+use Drupal\webform\Entity\Webform;
+
 /**
  * Tests for table elements.
  *
@@ -9,6 +11,14 @@
  */
 class WebformElementTableTest extends WebformElementBrowserTestBase {
 
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['webform', 'webform_ui', 'file'];
+
   /**
    * Webforms to load.
    *
@@ -20,30 +30,163 @@ class WebformElementTableTest extends WebformElementBrowserTestBase {
    * Tests table elements.
    */
   public function testTable() {
-    // Check display elements within a table.
+    global $base_path;
+
+    $webform = Webform::load('test_element_table');
+
     $this->drupalGet('/webform/test_element_table');
+
+    /**************************************************************************/
+    // Rendering.
+    /**************************************************************************/
+
+    // Check default table rendering.
     $this->assertRaw('<table class="js-form-wrapper responsive-enabled" data-drupal-selector="edit-table" id="edit-table" data-striping="1">');
-    $this->assertRaw('<th>First Name</th>');
-    $this->assertRaw('<th>Last Name</th>');
-    $this->assertRaw('<th>Gender</th>');
+    $this->assertPattern('#<th>First Name</th>\s+<th>Last Name</th>\s+<th>Gender</th>#');
     $this->assertRaw('<tr data-drupal-selector="edit-table-1" class="odd">');
     $this->assertRaw('<td><div class="js-form-item form-item js-form-type-textfield form-type-textfield js-form-item-table__1__first-name form-item-table__1__first-name form-no-label">');
     $this->assertRaw('<input data-drupal-selector="edit-table-1-first-name" type="text" id="edit-table-1-first-name" name="table__1__first_name" value="John" size="20" maxlength="255" class="form-text" />');
 
-    // Check rendering.
-    $this->drupalPostForm('/webform/test_element_table', [], t('Preview'));
-    $this->assertRaw('<th>First Name</th>');
-    $this->assertRaw('<th>Last Name</th>');
-    $this->assertRaw('<th>Gender</th>');
-    $this->assertRaw('<th>Markup</th>');
-    $this->assertRaw('<td>John</td>');
-    $this->assertRaw('<td>Smith</td>');
-    $this->assertRaw('<td>Male</td>');
-    $this->assertRaw('<td>{markup_1}</td>');
-    $this->assertRaw('<td>Jane</td>');
-    $this->assertRaw('<td>Doe</td>');
-    $this->assertRaw('<td>Female</td>');
-    $this->assertRaw('<td>{markup_2}</td>');
+    // Check webform table basic rendering.
+    $this->assertRaw('<table data-drupal-selector="edit-table-basic" class="webform-table responsive-enabled" id="edit-table-basic" data-striping="1">');
+    $this->assertRaw('<tr data-drupal-selector="edit-table-basic-01" class="webform-table-row odd">');
+    $this->assertRaw('<input data-drupal-selector="edit-table-basic-01-first-name" type="text" id="edit-table-basic-01-first-name" name="table_basic_01_first_name" value="" size="60" maxlength="255" class="form-text" />');
+
+    // Check webform table advanced rendering.
+    $this->assertRaw('<table data-drupal-selector="edit-table-advanced" class="webform-table sticky-enabled responsive-enabled" id="edit-table-advanced" data-striping="1">');
+    $this->assertPattern('#<th width="50%">Composite</th>\s+<th width="50%">Nested</th>#');
+
+    // Check webform table states rendering.
+    $this->assertRaw('<table data-drupal-selector="edit-table-states" class="webform-table responsive-enabled" id="edit-table-states" data-drupal-states="{&quot;invisible&quot;:{&quot;.webform-submission-test-element-table-add-form :input[name=\u0022table_rows\u0022]&quot;:{&quot;value&quot;:&quot;&quot;}}}" data-striping="1">');
+    $this->assertRaw('<tr data-drupal-selector="edit-table-states-01" class="webform-table-row js-form-item odd" data-drupal-states="{&quot;visible&quot;:{&quot;.webform-submission-test-element-table-add-form :input[name=\u0022table_rows\u0022]&quot;:{&quot;value&quot;:{&quot;greater&quot;:&quot;0&quot;}}}}">');
+
+    /**************************************************************************/
+    // Display.
+    /**************************************************************************/
+
+    $edit = [
+      'table_basic_01_first_name' => 'Ringo',
+      'table_basic_01_last_name' => 'Starr',
+      'table_basic_01_gender' => 'Male',
+      'table_advanced_01_first_name' => 'John',
+      'table_advanced_01_last_name' => 'Lennon',
+      'table_advanced_01_gender' => 'Male',
+    ];
+    $this->drupalPostForm('/webform/test_element_table', $edit, t('Preview'));
+
+    // Check data.
+    $this->assertRaw("table__1__first_name: John
+table__1__last_name: Smith
+table__1__gender: Male
+table__2__first_name: Jane
+table__2__last_name: Doe
+table__2__gender: Female
+table_basic_01_first_name: Ringo
+table_basic_01_last_name: Starr
+table_basic_01_gender: Male
+table_advanced_01_address: null
+table_advanced_01_first_name: John
+table_advanced_01_last_name: Lennon
+table_advanced_01_gender: Male
+table_advanced_01_managed_file: null
+table_rows: '1'
+table_advanced_01_textfield: ''
+table_advanced_02_textfield: ''
+table_advanced_03_textfield: ''
+table_advanced_04_textfield: ''");
+
+    // Check default table display.
+    $this->assertPattern('#<th>First Name</th>\s+<th>Last Name</th>\s+<th>Gender</th>\s+<th>Markup</th>#');
+    $this->assertPattern('#<td>John</td>\s+<td>Smith</td>\s+<td>Male</td>\s+<td>{markup_1}</td>#');
+    $this->assertPattern('#<td>Jane</td>\s+<td>Doe</td>\s+<td>Female</td>\s+<td>{markup_2}</td>#');
+
+    // Check basic table display.
+    $this->assertPattern('#<label>table_basic</label>\s+<table class="responsive-enabled" data-striping="1">#');
+    $this->assertPattern('#<tr class="odd">\s+<td>Ringo</td>\s+<td>Starr</td>\s+<td>Male</td>\s+<td>{markup_1}</td>\s+</tr>#');
+
+    // Check advanced table display.
+    $this->assertPattern('#<label>table_advanced</label>\s+<div><details class="webform-container webform-container-type-details#');
+    $this->assertPattern('<section class="js-form-item form-item js-form-wrapper form-wrapper webform-section" id="test_element_table--table_advanced_01_container">');
+
+    // Check states table display.
+    $this->assertPattern('<div class="webform-element webform-element-type-webform-table js-form-item form-item js-form-type-item form-type-item js-form-item-table-states form-item-table-states" id="test_element_table--table_states">');
+
+    /**************************************************************************/
+    // User interface.
+    /**************************************************************************/
+
+    $this->drupalLogin($this->rootUser);
+
+    // Check that add table row is not displayed in select element.
+    $this->drupalGet('/admin/structure/webform/manage/test_element_table/element/add');
+    $this->assertNoRaw('Table row');
+
+    // Check that add table row link is displayed.
+    $this->drupalGet('/admin/structure/webform/manage/test_element_table');
+    $this->assertLinkByHref("${base_path}admin/structure/webform/manage/test_element_table/element/add/webform_table_row?parent=table_basic");
+
+    // Check that add table row without a parent table returns a 404 error.
+    $this->drupalGet('/admin/structure/webform/manage/test_element_table/element/add/webform_table_row');
+    $this->assertResponse(404);
+
+    // Check default table row element key and title.
+    $this->drupalGet('/admin/structure/webform/manage/test_element_table/element/add/webform_table_row', ['query' => ['parent' => 'table_basic']]);
+    $this->assertFieldByName('properties[title]', 'Basic Person (2)');
+    $this->assertFieldByName('key', 'table_basic_02');
+
+    // Check table row element can duplicate sub elements from the
+    // first table row.
+    $this->drupalGet('/admin/structure/webform/manage/test_element_table/element/add/webform_table_row', ['query' => ['parent' => 'table_basic']]);
+    $this->assertFieldByName('properties[duplicate]', TRUE);
+
+    // Check table row element sub elements are duplicated.
+    $this->drupalPostForm('/admin/structure/webform/manage/test_element_table/element/add/webform_table_row', [], t('Save'), ['query' => ['parent' => 'table_basic']]);
+    $this->assertRaw('>table_basic_02<');
+    $this->assertRaw('>table_basic_02_first_name<');
+    $this->assertRaw('>table_basic_02_last_name<');
+    $this->assertRaw('>table_basic_02_gender<');
+    $this->assertRaw('>table_basic_02_markup<');
+
+    // Check table row element sub elements are NOT duplicated.
+    $this->drupalPostForm('/admin/structure/webform/manage/test_element_table/element/add/webform_table_row', ['properties[duplicate]' => FALSE], t('Save'), ['query' => ['parent' => 'table_basic']]);
+    $this->assertRaw('>table_basic_03<');
+    $this->assertNoRaw('>table_basic_03_first_name<');
+    $this->assertNoRaw('>table_basic_03_last_name<');
+    $this->assertNoRaw('>table_basic_03_gender<');
+    $this->assertNoRaw('>table_basic_03_markup<');
+
+    // Check default table row element key and title.
+    $this->drupalGet('/admin/structure/webform/manage/test_element_table/element/add/textfield', ['query' => ['parent' => 'table_basic_01']]);
+    $this->assertRaw("Element keys are automatically prefixed with parent row's key.");
+    $this->assertRaw('<span class="field-prefix">table_basic_01_</span>');
+
+    // Check that elements are prefixed with row key.
+    $edit = [
+      'key' => 'testing',
+      'properties[title]' => 'Testing',
+    ];
+    $options = ['query' => ['parent' => 'table_basic_01']];
+    $this->drupalPostForm('/admin/structure/webform/manage/test_element_table/element/add/textfield', $edit, t('Save'), $options);
+    $this->assertRaw('>table_basic_01_testing<');
+
+    // Check table row element can NOT duplicate sub elements from the
+    // first table row.
+    $webform->setElementProperties('textfield', [
+      '#type' => 'textfield',
+      'title' => 'textfield',
+    ], 'table_basic_01')->save();
+    $this->drupalGet('/admin/structure/webform/manage/test_element_table/element/add/webform_table_row', ['query' => ['parent' => 'table_basic']]);
+    $this->assertNoFieldByName('properties[duplicate]');
+
+    // Check prefix children disabled for table row.
+    $this->drupalGet('/admin/structure/webform/manage/test_element_table/element/add/webform_table_row', ['query' => ['parent' => 'table_prefix_children_false']]);
+    $this->assertFieldByName('properties[title]', '');
+    $this->assertFieldByName('key', '');
+
+    // Check prefix children disabled for table row element.
+    $this->drupalGet('/admin/structure/webform/manage/test_element_table/element/add/textfield', ['query' => ['parent' => 'table_prefix_children_false_01']]);
+    $this->assertNoRaw("Element keys are automatically prefixed with parent row's key.");
+    $this->assertNoRaw('<span class="field-prefix">table_basic_01_</span>');
   }
 
 }
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementTermReferenceTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementTermReferenceTest.php
index 5396461051..5851bafe66 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementTermReferenceTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementTermReferenceTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\webform\Functional\Element;
 
+use Drupal\taxonomy\Entity\Term;
 use Drupal\webform\Entity\Webform;
 
 /**
@@ -108,6 +109,23 @@ public function testTermReference() {
     $this->postSubmission($webform, $edit, t('Preview'));
     $this->assertRaw('<label>webform_term_select_breadcrumb_advanced</label>');
     $this->assertRaw('<div class="item-list"><ul><li>Parent 1 › Parent 1: Child 1</li><li>Parent 1 › Parent 1: Child 2</li></ul></div>');
+
+    // Unpublish term:2.
+    Term::load(2)->setUnpublished()->save();
+
+    $this->drupalGet('/webform/test_element_term_reference');
+
+    // Check term select tree default.
+    $this->assertRaw('<option value="1">Parent 1</option>');
+    $this->assertNoRaw('<option value="2">-Parent 1: Child 1</option>');
+    $this->assertRaw('<option value="3">-Parent 1: Child 2</option>');
+    $this->assertRaw('<option value="4">-Parent 1: Child 3</option>');
+
+    // Check term select breadcrumb default.
+    $this->assertRaw('<option value="1">Parent 1</option>');
+    $this->assertNoRaw('<option value="2">Parent 1 › Parent 1: Child 1</option>');
+    $this->assertRaw('<option value="3">Parent 1 › Parent 1: Child 2</option>');
+    $this->assertRaw('<option value="4">Parent 1 › Parent 1: Child 3</option>');
   }
 
 }
diff --git a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerRemotePostTest.php b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerRemotePostTest.php
index b2ed874a5c..ac4c5749ff 100644
--- a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerRemotePostTest.php
+++ b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerRemotePostTest.php
@@ -193,7 +193,7 @@ public function testRemotePostHandler() {
 
     // Check 404 Not Found with custom error uri.
     $this->postSubmission($webform, ['response_type' => '404']);
-    $this->assertNoRaw('This is a custom 404 not found message.');
+    $this->assertRaw('This is a custom 404 not found message.');
     $this->assertUrl($webform->toUrl('canonical', ['query' => ['error' => '1']])->setAbsolute()->toString());
 
     /**************************************************************************/
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsDraftTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsDraftTest.php
index 43e746d8a2..822cfa2699 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsDraftTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsDraftTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\webform\Functional\Settings;
 
+use Drupal\Component\Utility\Html;
+use Drupal\user\Entity\User;
 use Drupal\webform\Entity\Webform;
 use Drupal\webform\Entity\WebformSubmission;
 use Drupal\Tests\webform\Functional\WebformBrowserTestBase;
@@ -75,6 +77,11 @@ public function testDraft() {
       $this->drupalGet("webform/$webform_id/drafts");
       $this->assertResponse(200);
 
+      // Check draft title and info.
+      $account = ($is_authenticated) ? $normal_user : User::getAnonymousUser();
+      $this->assertRaw('<title>' . Html::escape('Drafts for ' . $webform->label() . ' for ' . ($account->getAccountName() ?: 'Anonymous') . ' | Drupal') . '</title>');
+      $this->assertRaw('<div>1 draft</div>');
+
       // Check loaded draft message.
       $this->drupalGet("webform/$webform_id");
       $this->assertNoRaw('Your draft has been saved');
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPrepopulateTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPrepopulateTest.php
index b5d279ce70..cbd445ad61 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPrepopulateTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPrepopulateTest.php
@@ -137,7 +137,7 @@ public function testPrepopulate() {
 
     $this->drupalLogin($this->rootUser);
 
-    // Check query string parameters be be transfered from canonical to test.
+    // Check query string parameters to be transfered from canonical to test.
     // @see webform_menu_local_tasks_alter
     $route_options = ['query' => ['source_entity_type' => 'webform', 'source_entity_id' => 'contact']];
     $this->drupalGet('/webform/test_form_prepopulate', $route_options);
diff --git a/web/modules/webform/tests/src/Functional/Token/WebformTokenSubmissionValueTest.php b/web/modules/webform/tests/src/Functional/Token/WebformTokenSubmissionValueTest.php
index cde873f888..75ae2a5611 100644
--- a/web/modules/webform/tests/src/Functional/Token/WebformTokenSubmissionValueTest.php
+++ b/web/modules/webform/tests/src/Functional/Token/WebformTokenSubmissionValueTest.php
@@ -126,6 +126,11 @@ public function testWebformTokenSubmissionValue() {
 last_name: Smith
 </pre>',
 
+      // Markup.
+      'webform_submission:values:webform_markup' => '*This is some basic HTML.*
+',
+      'webform_submission:values:webform_markup:html' => '<strong>This is some basic HTML.</strong>',
+
       // Submission limits.
       'webform_submission:limit:webform' => '100',
       'webform_submission:total:webform' => '1',
diff --git a/web/modules/webform/tests/src/Kernel/WebformEntityElementsValidationTest.php b/web/modules/webform/tests/src/Kernel/WebformEntityElementsValidationTest.php
index 887a9f5451..8b1ad0f7eb 100644
--- a/web/modules/webform/tests/src/Kernel/WebformEntityElementsValidationTest.php
+++ b/web/modules/webform/tests/src/Kernel/WebformEntityElementsValidationTest.php
@@ -152,6 +152,32 @@ public function testValidate() {
           'The <em class="placeholder">root</em> (webform_wizard_page) is a root element that can not be used as child to another element',
         ],
       ],
+
+      // Check validate table hierarchy.
+      [
+        'getElementsRaw' => 'empty: empty',
+        'getElementsOriginalRaw' => 'empty: empty',
+        'getElementsInitializedAndFlattened' => [
+          'table' => [
+            '#type' => 'webform_table',
+            '#webform_key' => 'table',
+          ],
+          'table_row' => [
+            '#type' => 'webform_table_row',
+            '#webform_key' => 'table_row',
+            '#webform_parent_key' => 'table',
+          ],
+          'table_row_invalid' => [
+            '#type' => 'webform_table_row',
+            '#webform_key' => 'table_row',
+            '#webform_parent_key' => NULL,
+          ],
+        ],
+        'messages' => [
+          'The <em class="placeholder">table_row_invalid</em> (webform_table_row) must be with in a <em class="placeholder">Table</em> (webform_table) element.',
+        ],
+      ],
+
 /*
       // Check validate rendering.
       [
diff --git a/web/modules/webform/tests/src/Kernel/WebformSubmissionStorageTest.php b/web/modules/webform/tests/src/Kernel/WebformSubmissionStorageTest.php
index 03b97e76d9..83347112bc 100644
--- a/web/modules/webform/tests/src/Kernel/WebformSubmissionStorageTest.php
+++ b/web/modules/webform/tests/src/Kernel/WebformSubmissionStorageTest.php
@@ -97,7 +97,7 @@ public function testPurge($webform_purging, $webform_submissions_definition, $pu
     $query->accessCheck(FALSE);
     $query->condition('webform_id', $webform_no_purging->id());
     $result = $query->execute();
-    $this->assertEquals(count($webform_submissions_definition), count($result), 'No purging is executed when webform not not set up to purge.');
+    $this->assertEquals(count($webform_submissions_definition), count($result), 'No purging is executed when webform is not set up to purge.');
 
     $query = \Drupal::entityTypeManager()->getStorage('webform_submission')->getQuery();
     $query->accessCheck(FALSE);
diff --git a/web/modules/webform/tests/src/Unit/Utility/WebformElementHelperTest.php b/web/modules/webform/tests/src/Unit/Utility/WebformElementHelperTest.php
index f1fe3f6c9d..edcb8441bf 100644
--- a/web/modules/webform/tests/src/Unit/Utility/WebformElementHelperTest.php
+++ b/web/modules/webform/tests/src/Unit/Utility/WebformElementHelperTest.php
@@ -131,11 +131,40 @@ public function providerRemoveIgnoredProperties() {
       ['#tree' => TRUE, '#value' => 'text', '#element_validate' => 'some_function'],
       ['#value' => 'text'],
     ];
+    // Remove #ajax: string
+    $tests[] = [
+      ['#ajax' => 'some_function'],
+      [],
+    ];
+    // Don't remove #ajax: FALSE.
+    // @see @see \Drupal\webform\Element\WebformComputedBase
+    $tests[] = [
+      ['#ajax' => FALSE],
+      ['#ajax' => FALSE],
+    ];
     // Remove #subelement__tree and #subelement__element_validate.
     $tests[] = [
       ['#subelement__tree' => TRUE, '#value' => 'text', '#subelement__element_validate' => 'some_function'],
       ['#value' => 'text'],
     ];
+    // Remove random nested #element_validate.
+    $tests[] = [
+      ['random' => ['#element_validate' => 'some_function']],
+      ['random' => []],
+    ];
+    $tests[] = [
+      ['#prefix' => ['#markup' => 'some_markup', '#element_validate' => 'some_function']],
+      ['#prefix' => ['#markup' => 'some_markup']],
+    ];
+    // Remove any *_validate(s) and *_callback(s).
+    $tests[] = [
+      ['random' => ['#some_random_validate' => 'some_function']],
+      ['random' => []],
+    ];
+    $tests[] = [
+      ['random' => ['#some_random_callbacks' => 'some_function']],
+      ['random' => []],
+    ];
     return $tests;
   }
 
diff --git a/web/modules/webform/tests/src/Unit/Utility/WebformOptionsHelperTest.php b/web/modules/webform/tests/src/Unit/Utility/WebformOptionsHelperTest.php
index 68ea12fbe4..802f4f3294 100644
--- a/web/modules/webform/tests/src/Unit/Utility/WebformOptionsHelperTest.php
+++ b/web/modules/webform/tests/src/Unit/Utility/WebformOptionsHelperTest.php
@@ -73,6 +73,7 @@ public function testGetOptionsText(array $values, array $options, $expected) {
   public function providerGetOptionsText() {
     $tests[] = [['value'], ['value' => 'text'], ['text']];
     $tests[] = [[1, 3], [1 => 'One', 2 => 'Two', 'optgroup' => [3 => 'Three']], ['One', 'Three']];
+    $tests[] = [[2], ['optgroup1' => [1 => 'One'], 'optgroup2' => [2 => 'Two']], ['Two']];
     return $tests;
   }
 
diff --git a/web/modules/webform/tests/themes/webform_test_bartik/webform_test_bartik.info.yml b/web/modules/webform/tests/themes/webform_test_bartik/webform_test_bartik.info.yml
index b9fbdec78f..8ba1221a39 100644
--- a/web/modules/webform/tests/themes/webform_test_bartik/webform_test_bartik.info.yml
+++ b/web/modules/webform/tests/themes/webform_test_bartik/webform_test_bartik.info.yml
@@ -5,7 +5,7 @@ name: 'Webform Test Bartik'
 description: 'Test Webform Bartik integration.'
 package: 'Webform Test'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/webform.info.yml b/web/modules/webform/webform.info.yml
index dbe35cb7d8..2218be9f7c 100644
--- a/web/modules/webform/webform.info.yml
+++ b/web/modules/webform/webform.info.yml
@@ -8,7 +8,7 @@ dependencies:
   - 'drupal:field'
   - 'drupal:user'
 
-# Information added by Drupal.org packaging script on 2020-03-18
-version: '8.x-5.9'
+# Information added by Drupal.org packaging script on 2020-05-05
+version: '8.x-5.11'
 project: 'webform'
-datestamp: 1584560018
+datestamp: 1588690393
diff --git a/web/modules/webform/webform.libraries.yml b/web/modules/webform/webform.libraries.yml
index 54ddaa713c..df15df09b9 100644
--- a/web/modules/webform/webform.libraries.yml
+++ b/web/modules/webform/webform.libraries.yml
@@ -816,6 +816,12 @@ webform.element.roles:
     - core/drupal
     - core/jquery.once
 
+webform.element.scale:
+  version: VERSION
+  css:
+    component:
+      css/webform.element.scale.css: {}
+
 webform.element.select:
   version: VERSION
   js:
@@ -895,6 +901,12 @@ webform.element.text_format:
   js:
     js/webform.element.text_format.js: {}
 
+webform.element.table:
+  version: VERSION
+  css:
+    component:
+      css/webform.element.table.css: {}
+
 webform.element.tableselect:
   version: VERSION
   js:
@@ -1090,13 +1102,13 @@ libraries.jquery.inputmask:
 
 libraries.jquery.intl-tel-input:
   remote: https://github.com/jackocnr/intl-tel-input
-  version: 'v16.0.0'
+  version: 'v16.1.0'
   license:
     name: MIT
     url: https://github.com/jackocnr/intl-tel-input/blob/master/LICENSE
     gpl-compatible: true
   cdn:
-    /libraries/jquery.intl-tel-input/: https://cdn.jsdelivr.net/gh/jackocnr/intl-tel-input@v16.0.0/
+    /libraries/jquery.intl-tel-input/: https://cdn.jsdelivr.net/gh/jackocnr/intl-tel-input@v16.1.0/
   css:
     component:
       /libraries/jquery.intl-tel-input/build/css/intlTelInput.min.css: { minified: true }
diff --git a/web/modules/webform/webform.module b/web/modules/webform/webform.module
index e2694c2ca1..b5f1f52eb5 100644
--- a/web/modules/webform/webform.module
+++ b/web/modules/webform/webform.module
@@ -261,7 +261,7 @@ function webform_menu_local_tasks_alter(&$data, $route_name, RefinableCacheableD
     }
   }
 
-  // Allow webform query string parameters be be transfered
+  // Allow webform query string parameters to be transfered
   // from canonical to test URL.
   $route_names = [
     'entity.webform.canonical', 'entity.webform.test_form',
diff --git a/web/modules/webform/webform.tokens.inc b/web/modules/webform/webform.tokens.inc
index 903fd59d0d..fcb3bc0d63 100644
--- a/web/modules/webform/webform.tokens.inc
+++ b/web/modules/webform/webform.tokens.inc
@@ -12,17 +12,18 @@
 use Drupal\Core\Render\BubbleableMetadata;
 use Drupal\Core\Render\Markup;
 use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Url;
 use Drupal\user\Entity\User;
 use Drupal\webform\Element\WebformHtmlEditor;
 use Drupal\webform\Plugin\WebformElementManagerInterface;
 use Drupal\webform\Plugin\WebformElementEntityReferenceInterface;
 use Drupal\webform\Plugin\WebformElement\WebformComputedBase;
+use Drupal\webform\Plugin\WebformElement\WebformMarkupBase;
 use Drupal\webform\Utility\WebformDateHelper;
 use Drupal\webform\Utility\WebformHtmlHelper;
 use Drupal\webform\Utility\WebformLogicHelper;
 use Drupal\webform\WebformInterface;
 use Drupal\webform\WebformSubmissionInterface;
-use Drupal\Core\Url;
 
 /**
  * Implements hook_token_info().
@@ -929,6 +930,14 @@ function _webform_token_get_submission_value($value_token, array $options, Webfo
     return $element_plugin->getValue($element, $webform_submission);
   }
 
+  // Always get rendered markup for a markup element.
+  if ($element_plugin instanceof WebformMarkupBase) {
+    $format_method = (empty($options['html'])) ? 'buildText' : 'buildHtml';
+    $element['#display_on'] = WebformMarkupBase::DISPLAY_ON_BOTH;
+    $token_value = $element_manager->invokeMethod($format_method, $element, $webform_submission, $options);
+    return \Drupal::service('renderer')->renderPlain($token_value);
+  }
+
   // Exit if no submission data and form element is not a container.
   if (!isset($submission_data[$element_key]) && !$element_plugin->isContainer($element)) {
     return NULL;
@@ -1133,7 +1142,8 @@ function _webform_token_get_interval_wait($interval_setting, BubbleableMetadata
   // Get last submission completed time.
   /** @var \Drupal\webform\WebformSubmissionStorageInterface $submission_storage */
   $submission_storage = \Drupal::entityTypeManager()->getStorage('webform_submission');
-  $last_submission = $submission_storage->getLastSubmission($webform, $source_entity, $account);
+  $options = ['access_check' => FALSE];
+  $last_submission = $submission_storage->getLastSubmission($webform, $source_entity, $account, $options);
   if (!$last_submission) {
     return '';
   }
-- 
GitLab