From c32f00d73f112ddbfb2bea91cc4801d19dfea3e6 Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Wed, 7 Jul 2021 11:54:00 -0500 Subject: [PATCH 01/53] Updating/re-enabling skipped/xfailed Dynamic Vegetation automated tests Signed-off-by: jckand-amzn --- .../hydra_test_utils.py | 6 ++--- .../AltitudeFilter_FilterStageToggle.py | 24 +++---------------- ...ynamicSliceInstanceSpawner_Embedded_E2E.py | 19 ++++++--------- ...ynamicSliceInstanceSpawner_External_E2E.py | 23 +++++++----------- .../test_DynamicSliceInstanceSpawner.py | 2 -- .../editor_dynveg_test_helper.py | 4 ++-- 6 files changed, 24 insertions(+), 54 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py index 2583109573..bb71d30d98 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py @@ -89,7 +89,7 @@ def launch_and_validate_results_launcher(launcher, level, remote_console_instanc :return: True if port is listening. """ port_listening = False - for conn in psutil.net_connections(): + for conn in process_utils.psutil.net_connections(): if 'port={}'.format(port) in str(conn): port_listening = True return port_listening @@ -110,8 +110,8 @@ def launch_and_validate_results_launcher(launcher, level, remote_console_instanc # Load the specified level in the launcher send_command_and_expect_response(remote_console_instance, - f"map {level}", - "LEVEL_LOAD_COMPLETE", timeout=30) + f"LoadLevel {level}", + "LEVEL_LOAD_END", timeout=30) # Monitor the console for expected lines for line in expected_lines: diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_FilterStageToggle.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_FilterStageToggle.py index bbdb925585..2fac361ced 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_FilterStageToggle.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/AltitudeFilter_FilterStageToggle.py @@ -36,8 +36,8 @@ class TestAltitudeFilterFilterStageToggle(EditorTestHelper): :return: None """ - PREPROCESS_INSTANCE_COUNT = 24 - POSTPROCESS_INSTANCE_COUNT = 18 + PREPROCESS_INSTANCE_COUNT = 44 + POSTPROCESS_INSTANCE_COUNT = 34 # Create empty level self.test_success = self.create_level( @@ -62,25 +62,7 @@ class TestAltitudeFilterFilterStageToggle(EditorTestHelper): dynveg.create_surface_entity("Surface_Entity_Parent", position, 16.0, 16.0, 1.0) # Add entity with Mesh to replicate creation of hills - hill_entity = dynveg.create_mesh_surface_entity_with_slopes("hill", position, 40.0, 40.0, 40.0) - - # Disable/Re-enable Mesh component due to ATOM-14299 - general.idle_wait(1.0) - editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [hill_entity.components[0]]) - is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0]) - if is_enabled: - print("Mesh component is still enabled") - else: - print("Mesh component was disabled") - editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [hill_entity.components[0]]) - is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0]) - if is_enabled: - print("Mesh component is now enabled") - else: - print("Mesh component is still disabled") - - # Increase Box Shape size to encompass the hills - vegetation.get_set_test(1, "Box Shape|Box Configuration|Dimensions", math.Vector3(100.0, 100.0, 100.0)) + hill_entity = dynveg.create_mesh_surface_entity_with_slopes("hill", position, 10.0) # Set a Min Altitude of 38 and Max of 40 in Vegetation Altitude Filter vegetation.get_set_test(3, "Configuration|Altitude Min", 38.0) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py index 4b0951acaf..6a99979a1f 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_Embedded_E2E.py @@ -9,9 +9,10 @@ import sys sys.path.append(os.path.dirname(os.path.abspath(__file__))) import azlmbr.asset as asset +import azlmbr.components as components import azlmbr.legacy.general as general import azlmbr.bus as bus -import azlmbr.entity as EntityId +import azlmbr.entity as entity import azlmbr.editor as editor import azlmbr.math as math import azlmbr.paths @@ -83,18 +84,12 @@ class TestDynamicSliceInstanceSpawnerEmbeddedEditor(EditorTestHelper): self.log(f"Expected {num_expected_instances} instances - Found {num_found} instances") self.test_success = self.test_success and num_found == num_expected_instances - # 5) Create a new entity with a Camera component for testing in the launcher + # 5) Move the default Camera entity for testing in the launcher cam_position = math.Vector3(512.0, 500.0, 35.0) - camera_component = ["Camera"] - new_entity_id2 = editor.ToolsApplicationRequestBus( - bus.Broadcast, "CreateNewEntityAtPosition", cam_position, EntityId.EntityId() - ) - if new_entity_id2.IsValid(): - self.log("Camera entity created") - camera_entity = hydra.Entity("Camera Entity", new_entity_id2) - camera_entity.components = [] - for component in camera_component: - camera_entity.components.append(hydra.add_component(component, new_entity_id2)) + search_filter = entity.SearchFilter() + search_filter.names = ["Camera"] + search_entity_ids = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter) + components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position) # 6) Save and export to engine general.save_level() diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py index 892549d414..70030ff359 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynamicSliceInstanceSpawner_External_E2E.py @@ -11,7 +11,8 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__))) import azlmbr.legacy.general as general import azlmbr.asset as asset import azlmbr.bus as bus -import azlmbr.entity as EntityId +import azlmbr.components as components +import azlmbr.entity as entity import azlmbr.editor as editor import azlmbr.math as math import azlmbr.paths @@ -68,7 +69,7 @@ class TestDynamicSliceInstanceSpawnerExternalEditor(EditorTestHelper): veg_area_required_components = ["Vegetation Layer Spawner", "Box Shape", "Vegetation Asset List", "Script Canvas"] new_entity_id = editor.ToolsApplicationRequestBus( - bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId() + bus.Broadcast, "CreateNewEntityAtPosition", entity_position, entity.EntityId() ) if new_entity_id.IsValid(): self.log("Spawner entity created") @@ -106,18 +107,12 @@ class TestDynamicSliceInstanceSpawnerExternalEditor(EditorTestHelper): self.log(f"Expected {num_expected_instances} instances - Found {num_found} instances") self.test_success = self.test_success and num_found == num_expected_instances - # 5) Create a new entity with a Camera component for testing in the launcher - entity_position = math.Vector3(512.0, 500.0, 35.0) - camera_component = ["Camera"] - new_entity_id2 = editor.ToolsApplicationRequestBus( - bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId() - ) - if new_entity_id2.IsValid(): - self.log("Camera entity created") - camera_entity = hydra.Entity("Camera Entity", new_entity_id2) - camera_entity.components = [] - for component in camera_component: - camera_entity.components.append(hydra.add_component(component, new_entity_id2)) + # 5) Move the default Camera entity for testing in the launcher + cam_position = math.Vector3(512.0, 500.0, 35.0) + search_filter = entity.SearchFilter() + search_filter.names = ["Camera"] + search_entity_ids = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter) + components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position) # 6) Save and export to engine general.save_level() diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_DynamicSliceInstanceSpawner.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_DynamicSliceInstanceSpawner.py index 053c4ccbfd..eb74a5a144 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_DynamicSliceInstanceSpawner.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_DynamicSliceInstanceSpawner.py @@ -90,7 +90,6 @@ class TestDynamicSliceInstanceSpawner(object): @pytest.mark.SUITE_periodic @pytest.mark.dynveg_area @pytest.mark.parametrize("launcher_platform", ['windows']) - @pytest.mark.skip # ATOM-14703 def test_DynamicSliceInstanceSpawner_Embedded_E2E_Launcher(self, workspace, launcher, level, remote_console_instance, project, launcher_platform): @@ -126,7 +125,6 @@ class TestDynamicSliceInstanceSpawner(object): @pytest.mark.SUITE_periodic @pytest.mark.dynveg_area @pytest.mark.parametrize("launcher_platform", ['windows']) - @pytest.mark.skip # ATOM-14703 def test_DynamicSliceInstanceSpawner_External_E2E_Launcher(self, workspace, launcher, level, remote_console_instance, project, launcher_platform): diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py b/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py index 515009cb3a..09d4746fa6 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py @@ -34,7 +34,7 @@ def create_surface_entity(name, center_point, box_size_x, box_size_y, box_size_z return surface_entity -def create_mesh_surface_entity_with_slopes(name, center_point, scale_x, scale_y, scale_z): +def create_mesh_surface_entity_with_slopes(name, center_point, uniform_scale): # Creates an entity with the assigned mesh_asset as the specified scale and sets up as a planting surface mesh_asset_path = os.path.join("models", "sphere.azmodel") mesh_asset = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", mesh_asset_path, math.Uuid(), @@ -47,7 +47,7 @@ def create_mesh_surface_entity_with_slopes(name, center_point, scale_x, scale_y, if surface_entity.id.IsValid(): print(f"'{surface_entity.name}' created") hydra.get_set_test(surface_entity, 0, "Controller|Configuration|Mesh Asset", mesh_asset) - components.TransformBus(bus.Event, "SetLocalScale", surface_entity.id, math.Vector3(scale_x, scale_y, scale_z)) + components.TransformBus(bus.Event, "SetLocalUniformScale", surface_entity.id, uniform_scale) return surface_entity From 78752a23a76bf6b8d3f172a5c8cf6d90828e2417 Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Wed, 7 Jul 2021 14:30:24 -0500 Subject: [PATCH 02/53] Updating null renderer argument for launcher tests Signed-off-by: jckand-amzn --- .../editor_python_test_tools/hydra_test_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py index bb71d30d98..343eb5b12d 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py @@ -95,7 +95,7 @@ def launch_and_validate_results_launcher(launcher, level, remote_console_instanc return port_listening if null_renderer: - launcher.args.extend(["-NullRenderer"]) + launcher.args.extend(["-rhi=Null"]) # Start the Launcher with launcher.start(): From 0a68bbdf7ce830d8cf4a09da8037354d648c6b86 Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Wed, 7 Jul 2021 15:28:55 -0500 Subject: [PATCH 03/53] Updating camera position and null renderer args for launcher test Signed-off-by: jckand-amzn --- .../EditorScripts/LayerBlender_E2E_Editor.py | 26 +++++++------------ .../largeworlds/dyn_veg/test_LayerBlender.py | 4 +-- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py index c4dfbbf4fe..3543b4c23c 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerBlender_E2E_Editor.py @@ -18,9 +18,9 @@ import azlmbr.areasystem as areasystem import azlmbr.legacy.general as general import azlmbr import azlmbr.bus as bus -import azlmbr.editor as editor +import azlmbr.components as components import azlmbr.math as math -import azlmbr.entity as EntityId +import azlmbr.entity as entity import azlmbr.paths sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests')) @@ -134,20 +134,14 @@ class TestVegLayerBlenderCreated(EditorTestHelper): purple_count += 1 self.test_success = pink_count == purple_count and (pink_count + purple_count == num_expected) and self.test_success - # 5) Create a new entity with a Camera component for testing in the launcher - entity_position = math.Vector3(500.0, 500.0, 47.0) - rot_degrees_vector = math.Vector3(radians(-55.0), radians(28.5), radians(-17.0)) - camera_component = ["Camera"] - camera_id = editor.ToolsApplicationRequestBus( - bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId() - ) - if camera_id.IsValid(): - self.log("Camera entity created") - camera_entity = hydra.Entity("Camera Entity", camera_id) - camera_entity.components = [] - for component in camera_component: - camera_entity.components.append(hydra.add_component(component, camera_id)) - azlmbr.components.TransformBus(bus.Event, "SetLocalRotation", camera_id, rot_degrees_vector) + # 5) Move the default Camera entity for testing in the launcher + cam_position = math.Vector3(500.0, 500.0, 47.0) + cam_rot_degrees_vector = math.Vector3(radians(-55.0), radians(28.5), radians(-17.0)) + search_filter = entity.SearchFilter() + search_filter.names = ["Camera"] + search_entity_ids = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter) + components.TransformBus(bus.Event, "MoveEntity", search_entity_ids[0], cam_position) + azlmbr.components.TransformBus(bus.Event, "SetLocalRotation", search_entity_ids[0], cam_rot_degrees_vector) # 6) Save and export level general.save_level() diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerBlender.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerBlender.py index 3c16420a30..2620a7d50a 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerBlender.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerBlender.py @@ -68,7 +68,6 @@ class TestLayerBlender(object): "Entity has a Box Shape component", "Blender Configuration|Vegetation Areas: SUCCESS", "Blender Box Shape|Box Configuration|Dimensions: SUCCESS", - "Camera entity created", "LayerBlender_E2E_Editor: result=SUCCESS" ] @@ -85,12 +84,11 @@ class TestLayerBlender(object): @pytest.mark.BAT @pytest.mark.SUITE_periodic @pytest.mark.dynveg_area - @pytest.mark.xfail @pytest.mark.parametrize("launcher_platform", ['windows']) def test_LayerBlender_E2E_Launcher(self, workspace, project, launcher, level, remote_console_instance, launcher_platform): - launcher.args.extend(["-NullRenderer"]) + launcher.args.extend(["-rhi=Null"]) launcher.start() assert launcher.is_alive(), "Launcher failed to start" From 6308d01456252a1a12b23c844a8235ef93b07252 Mon Sep 17 00:00:00 2001 From: evanchia Date: Wed, 30 Jun 2021 15:29:06 -0700 Subject: [PATCH 04/53] Minor changes to system example test to match docs Signed-off-by: evanchia --- .../tests/example/test_system_example.py | 94 +++++++++---------- 1 file changed, 46 insertions(+), 48 deletions(-) diff --git a/Tools/LyTestTools/tests/example/test_system_example.py b/Tools/LyTestTools/tests/example/test_system_example.py index 3cb6128802..c4f4812428 100755 --- a/Tools/LyTestTools/tests/example/test_system_example.py +++ b/Tools/LyTestTools/tests/example/test_system_example.py @@ -3,7 +3,7 @@ Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright SPDX-License-Identifier: Apache-2.0 OR MIT -Example test using LyTestTools to test Lumberyard. +Example test using LyTestTools to test Open 3D Engine. """ # Python built-in dependencies. import logging @@ -11,7 +11,7 @@ import logging # Third party dependencies. import pytest -# ly_test_tools dependencies. +# Optional ly_test_tools dependencies. import ly_test_tools.log.log_monitor import ly_remote_console.remote_console_commands as remote_console_commands @@ -22,28 +22,6 @@ import ly_remote_console.remote_console_commands as remote_console_commands logger = logging.getLogger(__name__) -@pytest.fixture -def remote_console(request): - """ - Creates a RemoteConsole() class instance to send console commands to the - Lumberyard client console. - :param request: _pytest.fixtures.SubRequest class that handles getting - a pytest fixture from a pytest function/fixture. - :return: ly_remote_console.remote_console_commands.RemoteConsole class instance - representing the Lumberyard remote console executable. - """ - # Initialize the RemoteConsole object to send commands to the Lumberyard client console. - console = remote_console_commands.RemoteConsole() - - # Custom teardown method for this remote_console fixture. - def teardown(): - console.stop() - - # Utilize request.addfinalizer() to add custom teardown() methods. - request.addfinalizer(teardown) # This pattern must be used in pytest version - - return console - # Shared parameters & fixtures for all test methods inside the TestSystemExample class. @pytest.mark.usefixtures("automatic_process_killer") @pytest.mark.parametrize('project', ['AutomatedTesting']) @@ -55,6 +33,41 @@ class TestSystemExample(object): For this test, we placed unique test values in test methods and shared test values in the test class. We also assume building has already been done, but the test should error if the build is mis-configured. """ + + # This test method only needs pytest.mark report values and shared test class parameters. + @pytest.mark.parametrize('processes_to_kill', ['Editor.exe']) + @pytest.mark.parametrize("launcher_platform", ['windows_editor']) + def test_SystemTestExample_WindowsPlatform_LaunchEditor(self, editor, processes_to_kill, launcher_platform): + """ + Tests launching the O3DE Editor is successful with the current build. + """ + # Launch the O3DE Editor & verify load is successful: + with editor.start(): + assert editor.is_alive(), ( + 'Editor failed to launch for the current O3DE build.') + + @pytest.fixture + def remote_console(request): + """ + Creates a RemoteConsole() class instance to send console commands to the + O3DE client console. + :param request: _pytest.fixtures.SubRequest class that handles getting + a pytest fixture from a pytest function/fixture. + :return: ly_remote_console.remote_console_commands.RemoteConsole class instance + representing the O3DE Remote Console executable. + """ + # Initialize the RemoteConsole object to send commands to the O3DE client console. + console = remote_console_commands.RemoteConsole() + + # Custom teardown method for this remote_console fixture. + def teardown(): + console.stop() + + # Utilize request.addfinalizer() to add custom teardown() methods. + request.addfinalizer(teardown) # This pattern must be used in pytest version + + return console + # This test method needs specific parameters not shared by all other tests in the class. # For targeting specific launchers, use the 'launcher_platform' pytest param like below: # @pytest.mark.parametrize("launcher_platform", ['android']) @@ -62,39 +75,24 @@ class TestSystemExample(object): # @pytest.mark.parametrize("asset_processor_platform", ['android']) @pytest.mark.parametrize('level', ['simple_jacklocomotion']) @pytest.mark.parametrize('load_wait', [120]) - @pytest.mark.test_case_id('C16806863') - def test_SystemTestExample_AllSupportedPlatforms_LaunchAutomatedTesting( - # launcher_platform, asset_processor_platform, # Re-add these here if you plan to use them. - self, launcher, remote_console, level, load_wait): + def test_SystemTestExample_AllSupportedPlatforms_LaunchAutomatedTesting(self, launcher, remote_console, level, + load_wait): """ - Tests launching the AutomatedTesting then launches the Lumberyard client & + Tests launching the AutomatedTesting then launches the O3DE client & loads the "simple_jacklocomotion" level using the remote console. Assumes the user already setup & built their machine for the test. """ - # Launch the Lumberyard client & remote console test case: + # Launch the O3DE client & remote console test case: with launcher.start(): remote_console.start() + # Wait for the expected log line to appear launcher_load = remote_console.expect_log_line( match_string='Level system is loading "simple_jacklocomotion"', timeout=load_wait) # Assert loading was successful using remote console logs: - assert launcher_load, ( - 'Launcher failed to load Lumberyard client with the ' - f'"{level}" level - waited "{load_wait}" seconds.') - - # This test method only needs pytest.mark report values and shared test class parameters. - @pytest.mark.parametrize('processes_to_kill', ['Editor.exe']) - @pytest.mark.parametrize("launcher_platform", ['windows_editor']) - @pytest.mark.test_case_id('C16806864') - def test_SystemTestExample_AllSupportedPlatforms_LaunchEditor(self, editor, processes_to_kill, launcher_platform): - """ - Tests launching the Lumberyard Editor is successful with the current build. - """ - # Launch the Lumberyard editor & verify load is successful: - with editor.start(): - assert editor.is_alive(), ( - 'Editor failed to launch for the current Lumberyard build.') + assert launcher_load, ('Launcher failed to load O3DE client with the "{level}" level - waited "{load_wait}" ' + 'seconds.') # Log monitoring example test. @pytest.mark.parametrize('level', ['simple_jacklocomotion']) @@ -106,7 +104,7 @@ class TestSystemExample(object): """ Tests that the logging paths created by LyTestTools can be monitored for results using the log monitor. """ - # Launch the Lumberyard client & initialize the log monitor. + # Launch the O3DE client & initialize the log monitor. file_to_monitor = launcher.workspace.info_log_path log_monitor = ly_test_tools.log.log_monitor.LogMonitor(launcher=launcher, log_file_path=file_to_monitor) @@ -115,7 +113,7 @@ class TestSystemExample(object): for expected_line in expected_lines: logger.info(expected_line) - # Start the Lumberyard client & test that the lines we logged can be viewed by the log monitor. + # Start the O3DE client & test that the lines we logged can be viewed by the log monitor. with launcher.start(): log_test = log_monitor.monitor_log_for_lines( expected_lines=expected_lines, # Defaults to None. From 9067fc3b99af1ff01384a873136e05262f1ed1c2 Mon Sep 17 00:00:00 2001 From: evanchia Date: Thu, 8 Jul 2021 10:24:49 -0700 Subject: [PATCH 05/53] Updating/Removing LyTestTools sample tests Signed-off-by: evanchia --- Tools/LyTestTools/tests/example/__init__.py | 5 - .../tests/example/test_system_example.py | 127 ------------------ Tools/LyTestTools/tests/integ/sanity_tests.py | 17 ++- 3 files changed, 14 insertions(+), 135 deletions(-) delete mode 100755 Tools/LyTestTools/tests/example/__init__.py delete mode 100755 Tools/LyTestTools/tests/example/test_system_example.py diff --git a/Tools/LyTestTools/tests/example/__init__.py b/Tools/LyTestTools/tests/example/__init__.py deleted file mode 100755 index e200fa77d0..0000000000 --- a/Tools/LyTestTools/tests/example/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -""" -Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - -SPDX-License-Identifier: Apache-2.0 OR MIT -""" diff --git a/Tools/LyTestTools/tests/example/test_system_example.py b/Tools/LyTestTools/tests/example/test_system_example.py deleted file mode 100755 index c4f4812428..0000000000 --- a/Tools/LyTestTools/tests/example/test_system_example.py +++ /dev/null @@ -1,127 +0,0 @@ -""" -Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - -SPDX-License-Identifier: Apache-2.0 OR MIT - -Example test using LyTestTools to test Open 3D Engine. -""" -# Python built-in dependencies. -import logging - -# Third party dependencies. -import pytest - -# Optional ly_test_tools dependencies. -import ly_test_tools.log.log_monitor -import ly_remote_console.remote_console_commands as remote_console_commands - -# Configuring the logging is done in ly_test_tools at the following location: -# ~/dev/Tools/LyTestTools/ly_test_tools/_internal/log/py_logging_util.py - -# Use the following logging pattern to hook all test logging together: -logger = logging.getLogger(__name__) - - -# Shared parameters & fixtures for all test methods inside the TestSystemExample class. -@pytest.mark.usefixtures("automatic_process_killer") -@pytest.mark.parametrize('project', ['AutomatedTesting']) -class TestSystemExample(object): - """ - Example test case class to hold a set of test case methods. - - The amount of tests run is based on the parametrization stacking made in each test method or class. - For this test, we placed unique test values in test methods and shared test values in the test class. - We also assume building has already been done, but the test should error if the build is mis-configured. - """ - - # This test method only needs pytest.mark report values and shared test class parameters. - @pytest.mark.parametrize('processes_to_kill', ['Editor.exe']) - @pytest.mark.parametrize("launcher_platform", ['windows_editor']) - def test_SystemTestExample_WindowsPlatform_LaunchEditor(self, editor, processes_to_kill, launcher_platform): - """ - Tests launching the O3DE Editor is successful with the current build. - """ - # Launch the O3DE Editor & verify load is successful: - with editor.start(): - assert editor.is_alive(), ( - 'Editor failed to launch for the current O3DE build.') - - @pytest.fixture - def remote_console(request): - """ - Creates a RemoteConsole() class instance to send console commands to the - O3DE client console. - :param request: _pytest.fixtures.SubRequest class that handles getting - a pytest fixture from a pytest function/fixture. - :return: ly_remote_console.remote_console_commands.RemoteConsole class instance - representing the O3DE Remote Console executable. - """ - # Initialize the RemoteConsole object to send commands to the O3DE client console. - console = remote_console_commands.RemoteConsole() - - # Custom teardown method for this remote_console fixture. - def teardown(): - console.stop() - - # Utilize request.addfinalizer() to add custom teardown() methods. - request.addfinalizer(teardown) # This pattern must be used in pytest version - - return console - - # This test method needs specific parameters not shared by all other tests in the class. - # For targeting specific launchers, use the 'launcher_platform' pytest param like below: - # @pytest.mark.parametrize("launcher_platform", ['android']) - # If you want to target different AssetProcessor platforms, use asset_processor_platform: - # @pytest.mark.parametrize("asset_processor_platform", ['android']) - @pytest.mark.parametrize('level', ['simple_jacklocomotion']) - @pytest.mark.parametrize('load_wait', [120]) - def test_SystemTestExample_AllSupportedPlatforms_LaunchAutomatedTesting(self, launcher, remote_console, level, - load_wait): - """ - Tests launching the AutomatedTesting then launches the O3DE client & - loads the "simple_jacklocomotion" level using the remote console. - Assumes the user already setup & built their machine for the test. - """ - # Launch the O3DE client & remote console test case: - with launcher.start(): - remote_console.start() - # Wait for the expected log line to appear - launcher_load = remote_console.expect_log_line( - match_string='Level system is loading "simple_jacklocomotion"', - timeout=load_wait) - - # Assert loading was successful using remote console logs: - assert launcher_load, ('Launcher failed to load O3DE client with the "{level}" level - waited "{load_wait}" ' - 'seconds.') - - # Log monitoring example test. - @pytest.mark.parametrize('level', ['simple_jacklocomotion']) - @pytest.mark.parametrize('expected_lines', [['Log Monitoring test 1', 'Log Monitoring test 2']]) - @pytest.mark.parametrize('unexpected_lines', [['Unexpected test 1', 'Unexpected test 2']]) - @pytest.mark.test_case_id('C21202585') - def test_SystemTestExample_AllSupportedPlatforms_LogMonitoring(self, level, launcher, expected_lines, - unexpected_lines): - """ - Tests that the logging paths created by LyTestTools can be monitored for results using the log monitor. - """ - # Launch the O3DE client & initialize the log monitor. - file_to_monitor = launcher.workspace.info_log_path - log_monitor = ly_test_tools.log.log_monitor.LogMonitor(launcher=launcher, - log_file_path=file_to_monitor) - - # Generate log lines to the info log using logger. - for expected_line in expected_lines: - logger.info(expected_line) - - # Start the O3DE client & test that the lines we logged can be viewed by the log monitor. - with launcher.start(): - log_test = log_monitor.monitor_log_for_lines( - expected_lines=expected_lines, # Defaults to None. - unexpected_lines=unexpected_lines, # Defaults to None. - halt_on_unexpected=True, # Defaults to False. - timeout=60) # Defaults to 30 - - # Assert the log monitor detected expected lines and did not detect any unexpected lines. - assert log_test, ( - f'Log monitoring failed. Used expected_lines values: {expected_lines} & ' - f'unexpected_lines values: {unexpected_lines}') diff --git a/Tools/LyTestTools/tests/integ/sanity_tests.py b/Tools/LyTestTools/tests/integ/sanity_tests.py index c6c5ce0c31..6c1f1079a9 100755 --- a/Tools/LyTestTools/tests/integ/sanity_tests.py +++ b/Tools/LyTestTools/tests/integ/sanity_tests.py @@ -15,8 +15,6 @@ import ly_test_tools.builtin.helpers as helpers import ly_test_tools.environment.process_utils as process_utils import ly_test_tools.environment.waiter as waiter -pytestmark = pytest.mark.SUITE_smoke - logger = logging.getLogger(__name__) # Note: For device testing, device ids must exist in ~/ly_test_tools/devices.ini, see README.txt for more info. @@ -24,31 +22,44 @@ logger = logging.getLogger(__name__) @pytest.mark.parametrize("project", ["AutomatedTesting"]) class TestAutomatedTestingProject(object): + def test_StartGameLauncher_Sanity(self, project): + # Kill processes that may interfere with the test process_utils.kill_processes_named(names=process_utils.LY_PROCESS_KILL_LIST, ignore_extensions=True) try: + # Create the Workspace object workspace = helpers.create_builtin_workspace(project=project) + # Create the Launcher object and add args launcher = launcher_helper.create_launcher(workspace) - launcher.args.extend(['-NullRenderer', '-BatchMode']) + launcher.args.extend(['-NullRenderer']) + # Call the game client executable with launcher.start(): + # Wait for the process to exist waiter.wait_for(lambda: process_utils.process_exists(f"{project}.GameLauncher.exe", ignore_extensions=True)) finally: + # Clean up processes after the test is finished process_utils.kill_processes_named(names=process_utils.LY_PROCESS_KILL_LIST, ignore_extensions=True) @pytest.mark.skipif(not ly_test_tools.WINDOWS, reason="Editor currently only functions on Windows") def test_StartEditor_Sanity(self, project): + # Kill processes that may interfere with the test process_utils.kill_processes_named(names=process_utils.LY_PROCESS_KILL_LIST, ignore_extensions=True) try: + # Create the Workspace object workspace = helpers.create_builtin_workspace(project=project) + # Create the Launcher object and add args editor = launcher_helper.create_editor(workspace) editor.args.extend(['-NullRenderer', '-autotest_mode']) + # Call the Editor executable with editor.start(): + # Wait for the process to exist waiter.wait_for(lambda: process_utils.process_exists("Editor", ignore_extensions=True)) finally: + # Clean up processes after the test is finished process_utils.kill_processes_named(names=process_utils.LY_PROCESS_KILL_LIST, ignore_extensions=True) From bc7e12278cd39d4b495fa9dde226fe74423d8bdb Mon Sep 17 00:00:00 2001 From: evanchia Date: Thu, 8 Jul 2021 15:55:06 -0700 Subject: [PATCH 06/53] changed nullrenderer arg for sanity test Signed-off-by: evanchia --- Tools/LyTestTools/tests/integ/sanity_tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tools/LyTestTools/tests/integ/sanity_tests.py b/Tools/LyTestTools/tests/integ/sanity_tests.py index 6c1f1079a9..0aacfff8c6 100755 --- a/Tools/LyTestTools/tests/integ/sanity_tests.py +++ b/Tools/LyTestTools/tests/integ/sanity_tests.py @@ -33,7 +33,7 @@ class TestAutomatedTestingProject(object): # Create the Launcher object and add args launcher = launcher_helper.create_launcher(workspace) - launcher.args.extend(['-NullRenderer']) + launcher.args.extend(['-rhi=Null']) # Call the game client executable with launcher.start(): @@ -54,7 +54,7 @@ class TestAutomatedTestingProject(object): # Create the Launcher object and add args editor = launcher_helper.create_editor(workspace) - editor.args.extend(['-NullRenderer', '-autotest_mode']) + editor.args.extend(['-rhi=Null', '-autotest_mode']) # Call the Editor executable with editor.start(): From b07ed7817dd280a0710ad2450f488024f1824baa Mon Sep 17 00:00:00 2001 From: aaguilea Date: Fri, 9 Jul 2021 12:00:11 +0100 Subject: [PATCH 07/53] Fixed small bug with edit menu Signed-off-by: aaguilea --- Code/Editor/Core/LevelEditorMenuHandler.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Code/Editor/Core/LevelEditorMenuHandler.cpp b/Code/Editor/Core/LevelEditorMenuHandler.cpp index ab1229dc6b..5ca3a1dfe4 100644 --- a/Code/Editor/Core/LevelEditorMenuHandler.cpp +++ b/Code/Editor/Core/LevelEditorMenuHandler.cpp @@ -497,9 +497,15 @@ void LevelEditorMenuHandler::PopulateEditMenu(ActionManager::MenuWrapper& editMe // Hide Selection editMenu.AddAction(AzToolsFramework::HideSelection); - // Unhide All + // Show All editMenu.AddAction(AzToolsFramework::ShowAll); + // Lock Selection + editMenu.AddAction(AzToolsFramework::LockSelection); + + // UnLock All + editMenu.AddAction(AzToolsFramework::UnlockAll); + /* * The following block of code is part of the feature "Isolation Mode" and is temporarily * disabled for 1.10 release. From 9f5e91be88a0ecaa7b71c3e2b1582c524a322f9b Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Fri, 9 Jul 2021 15:43:44 -0500 Subject: [PATCH 08/53] Updating utility path for test import, and updating linked issue to disabled test Signed-off-by: jckand-amzn --- ...ayerSpawner_InstancesRefreshUsingCorrectViewportCamera.py | 2 +- .../Gem/PythonTests/largeworlds/dyn_veg/test_LayerSpawner.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesRefreshUsingCorrectViewportCamera.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesRefreshUsingCorrectViewportCamera.py index c99d180253..4752aeddbc 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesRefreshUsingCorrectViewportCamera.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_InstancesRefreshUsingCorrectViewportCamera.py @@ -13,7 +13,7 @@ import azlmbr.legacy.general as general import azlmbr.math as math sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests')) -from automatedtesting_shared.editor_test_helper import EditorTestHelper +from editor_python_test_tools.editor_test_helper import EditorTestHelper from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerSpawner.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerSpawner.py index 410bdbafed..2af848ffb1 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerSpawner.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_LayerSpawner.py @@ -121,7 +121,7 @@ class TestLayerSpawner(object): @pytest.mark.test_case_id("C30000751") @pytest.mark.SUITE_sandbox @pytest.mark.dynveg_misc - @pytest.mark.skip # ATOM-14828 + @pytest.mark.skip # https://github.com/o3de/o3de/issues/2038 def test_LayerSpawner_InstancesRefreshUsingCorrectViewportCamera(self, request, editor, level, launcher_platform): expected_lines = [ @@ -136,5 +136,6 @@ class TestLayerSpawner(object): editor, "LayerSpawner_InstancesRefreshUsingCorrectViewportCamera.py", expected_lines, - cfg_args=[level] + cfg_args=[level], + null_renderer=False ) From ea99ed11a3529a102b64762be6988096abdeb3bb Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Fri, 9 Jul 2021 16:52:22 -0500 Subject: [PATCH 09/53] Updating mesh surface creation, filtering, and expected instance counts Signed-off-by: jckand-amzn --- .../LayerSpawner_FilterStageToggle.py | 27 ++++--------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_FilterStageToggle.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_FilterStageToggle.py index 0224f6bc0a..fb1ac5a5ce 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_FilterStageToggle.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/LayerSpawner_FilterStageToggle.py @@ -34,8 +34,8 @@ class TestLayerSpawnerFilterStageToggle(EditorTestHelper): :return: None """ - PREPROCESS_INSTANCE_COUNT = 425 - POSTPROCESS_INSTANCE_COUNT = 430 + PREPROCESS_INSTANCE_COUNT = 21 + POSTPROCESS_INSTANCE_COUNT = 19 # Create empty level self.test_success = self.create_level( @@ -56,7 +56,6 @@ class TestLayerSpawnerFilterStageToggle(EditorTestHelper): vegetation_entity.add_component("Vegetation Altitude Filter") vegetation_entity.add_component("Vegetation Position Modifier") - # Create a child entity under vegetation area child_entity = hydra.Entity("child_entity") components_to_add = ["Random Noise Gradient", "Gradient Transform Modifier", "Box Shape"] @@ -66,29 +65,13 @@ class TestLayerSpawnerFilterStageToggle(EditorTestHelper): vegetation_entity.get_set_test(4, "Configuration|Position X|Gradient|Gradient Entity Id", child_entity.id) vegetation_entity.get_set_test(4, "Configuration|Position Y|Gradient|Gradient Entity Id", child_entity.id) - # Set the min and max values for Altitude Filter - vegetation_entity.get_set_test(3, "Configuration|Altitude Min", 32.0) - vegetation_entity.get_set_test(3, "Configuration|Altitude Max", 35.0) + vegetation_entity.get_set_test(3, "Configuration|Altitude Min", 34.0) + vegetation_entity.get_set_test(3, "Configuration|Altitude Max", 38.0) # Add entity with Mesh to replicate creation of hills and a flat surface to plant on dynveg.create_surface_entity("Flat Surface", position, 32.0, 32.0, 1.0) - hill_entity = dynveg.create_mesh_surface_entity_with_slopes("hill", position, 4.0, 4.0, 4.0) - - # Disable/Re-enable Mesh component due to ATOM-14299 - general.idle_wait(1.0) - editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [hill_entity.components[0]]) - is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0]) - if is_enabled: - print("Mesh component is still enabled") - else: - print("Mesh component was disabled") - editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [hill_entity.components[0]]) - is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', hill_entity.components[0]) - if is_enabled: - print("Mesh component is now enabled") - else: - print("Mesh component is still disabled") + hill_entity = dynveg.create_mesh_surface_entity_with_slopes("hill", position, 4.0) # Set the filter stage to preprocess and postprocess respectively and verify instance count vegetation_entity.get_set_test(0, "Configuration|Filter Stage", 1) From 35a60cdf1a7a85b61c669103c5e5b9f0d6ceedeb Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Fri, 9 Jul 2021 17:34:36 -0500 Subject: [PATCH 10/53] Removing unnecessary Mesh component refreshes and updating calls to scale meshes Signed-off-by: jckand-amzn --- .../MeshBlocker_InstancesBlockedByMesh.py | 17 +---------------- ...locker_InstancesBlockedByMeshHeightTuning.py | 17 +---------------- 2 files changed, 2 insertions(+), 32 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMesh.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMesh.py index d23f811f58..89367ca475 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMesh.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMesh.py @@ -82,22 +82,7 @@ class test_MeshBlocker_InstancesBlockedByMesh(EditorTestHelper): bus.Broadcast, "GetAssetIdByPath", os.path.join("objects", "_primitives", "_box_1x1.azmodel"), math.Uuid(), False) blocker_entity.get_set_test(1, "Controller|Configuration|Mesh Asset", cubeId) - components.TransformBus(bus.Event, "SetLocalScale", blocker_entity.id, math.Vector3(2.0, 2.0, 2.0)) - - # Disable/Re-enable Mesh component due to ATOM-14299 - general.idle_wait(1.0) - editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [blocker_entity.components[1]]) - is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1]) - if is_enabled: - print("Mesh component is still enabled") - else: - print("Mesh component was disabled") - editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [blocker_entity.components[1]]) - is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1]) - if is_enabled: - print("Mesh component is now enabled") - else: - print("Mesh component is still disabled") + components.TransformBus(bus.Event, "SetLocalUniformScale", blocker_entity.id, 2.0) # Verify spawned instance counts are accurate after addition of Blocker Entity num_expected = 160 # Number of "PurpleFlower"s that plant on a 10 x 10 surface minus 2m blocker cube diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMeshHeightTuning.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMeshHeightTuning.py index ad57f80776..4a3edcd0e9 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMeshHeightTuning.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/MeshBlocker_InstancesBlockedByMeshHeightTuning.py @@ -88,24 +88,9 @@ class test_MeshBlocker_InstancesBlockedByMeshHeightTuning(EditorTestHelper): bus.Broadcast, "GetAssetIdByPath", os.path.join("objects", "_primitives", "_box_1x1.azmodel"), math.Uuid(), False) blocker_entity.get_set_test(1, "Controller|Configuration|Mesh Asset", sphere_id) - components.TransformBus(bus.Event, "SetLocalScale", blocker_entity.id, math.Vector3(5.0, 5.0, 5.0)) + components.TransformBus(bus.Event, "SetLocalUniformScale", blocker_entity.id, 5.0) components.TransformBus(bus.Event, "SetLocalRotation", blocker_entity.id, math.Vector3(0.0, y_rotation, 0.0)) - # Disable/Re-enable Mesh component due to ATOM-14299 - general.idle_wait(1.0) - editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [blocker_entity.components[1]]) - is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1]) - if is_enabled: - print("Mesh component is still enabled") - else: - print("Mesh component was disabled") - editor.EditorComponentAPIBus(bus.Broadcast, 'EnableComponents', [blocker_entity.components[1]]) - is_enabled = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', blocker_entity.components[1]) - if is_enabled: - print("Mesh component is now enabled") - else: - print("Mesh component is still disabled") - # 5) Adjust the height Max percentage values of blocker blocker_entity.get_set_test(0, "Configuration|Mesh Height Percent Max", 0.8) From ceae858f099699db0a183707c9fa500a9ce06832 Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Fri, 9 Jul 2021 17:50:07 -0500 Subject: [PATCH 11/53] Updating to use of psutil directly Signed-off-by: jckand-amzn --- .../editor_python_test_tools/hydra_test_utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py index 343eb5b12d..382a6f27f7 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_test_utils.py @@ -6,13 +6,13 @@ SPDX-License-Identifier: Apache-2.0 OR MIT import logging import os -import tempfile +import psutil import ly_test_tools.log.log_monitor import ly_test_tools.environment.process_utils as process_utils import ly_test_tools.environment.waiter as waiter -from ly_remote_console.remote_console_commands import RemoteConsole as RemoteConsole from ly_remote_console.remote_console_commands import send_command_and_expect_response as send_command_and_expect_response + logger = logging.getLogger(__name__) @@ -89,7 +89,7 @@ def launch_and_validate_results_launcher(launcher, level, remote_console_instanc :return: True if port is listening. """ port_listening = False - for conn in process_utils.psutil.net_connections(): + for conn in psutil.net_connections(): if 'port={}'.format(port) in str(conn): port_listening = True return port_listening From 36a8c0a8cc5eac281afd7ae6818da53e82105f3e Mon Sep 17 00:00:00 2001 From: aaguilea Date: Mon, 12 Jul 2021 16:34:01 +0100 Subject: [PATCH 12/53] changed all amazon to o3de Signed-off-by: aaguilea --- .../AzToolsFramework/Viewport/ActionBus.h | 10 +++++----- .../ViewportSelection/EditorDefaultSelection.h | 2 +- .../Tests/ComponentModeTestDoubles.cpp | 2 +- .../Code/Source/Shape/EditorTubeShapeComponentMode.cpp | 2 +- Gems/PhysX/Code/Editor/ColliderComponentMode.cpp | 8 ++++---- Gems/PhysX/Code/Editor/EditorJointComponentMode.cpp | 4 ++-- .../SubComponentModes/EditorWhiteBoxDefaultMode.cpp | 4 ++-- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ActionBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ActionBus.h index d9bf0c40b9..e08bb13cac 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ActionBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ActionBus.h @@ -22,11 +22,11 @@ namespace AzToolsFramework /// @name Reverse URLs. /// Used to identify common actions and override them when necessary. //@{ - static const AZ::Crc32 s_backAction = AZ_CRC("com.amazon.action.common.back", 0xd772a2af); - static const AZ::Crc32 s_deleteAction = AZ_CRC("com.amazon.action.common.delete", 0x5731f6cb); - static const AZ::Crc32 s_duplicateAction = AZ_CRC("com.amazon.action.common.duplicate", 0x08ccf461); - static const AZ::Crc32 s_nextComponentMode = AZ_CRC("com.amazon.action.common.nextComponentMode", 0xcc26094f); - static const AZ::Crc32 s_previousComponentMode = AZ_CRC("com.amazon.action.common.previousComponentMode", 0x0d18ff39); + static const AZ::Crc32 s_backAction = AZ_CRC("com.o3de.action.common.back", 0xd772a2af); + static const AZ::Crc32 s_deleteAction = AZ_CRC("com.o3de.action.common.delete", 0x5731f6cb); + static const AZ::Crc32 s_duplicateAction = AZ_CRC("com.o3de.action.common.duplicate", 0x08ccf461); + static const AZ::Crc32 s_nextComponentMode = AZ_CRC("com.o3de.action.common.nextComponentMode", 0xcc26094f); + static const AZ::Crc32 s_previousComponentMode = AZ_CRC("com.o3de.action.common.previousComponentMode", 0x0d18ff39); //@} /// Specific Action properties to be sent to a type implementing diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.h b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.h index f92ee6b00b..73be188f2c 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorDefaultSelection.h @@ -98,7 +98,7 @@ namespace AzToolsFramework { } - AZ::Crc32 m_uri; //!< Unique identifier for the Action. (In the form 'com.amazon.action.---"). + AZ::Crc32 m_uri; //!< Unique identifier for the Action. (In the form 'com.o3de.action.---"). AZStd::vector> m_callbacks; //!< Callbacks associated with this Action (note: with multi-selections //!< there will be a callback per Entity/Component). AZStd::unique_ptr m_action; //!< The QAction associated with the overrideWidget for all ComponentMode actions. diff --git a/Code/Framework/AzToolsFramework/Tests/ComponentModeTestDoubles.cpp b/Code/Framework/AzToolsFramework/Tests/ComponentModeTestDoubles.cpp index caf6411eda..844fbb3e7f 100644 --- a/Code/Framework/AzToolsFramework/Tests/ComponentModeTestDoubles.cpp +++ b/Code/Framework/AzToolsFramework/Tests/ComponentModeTestDoubles.cpp @@ -196,7 +196,7 @@ namespace AzToolsFramework AZStd::vector PlaceHolderComponentMode::PopulateActionsImpl() { - const AZ::Crc32 placeHolderComponentModeAction = AZ_CRC_CE("com.amazon.action.placeholder.test"); + const AZ::Crc32 placeHolderComponentModeAction = AZ_CRC_CE("com.o3de.action.placeholder.test"); return AZStd::vector { diff --git a/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponentMode.cpp b/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponentMode.cpp index a45967a16c..48a68a30a5 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponentMode.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/EditorTubeShapeComponentMode.cpp @@ -22,7 +22,7 @@ namespace LmbrCentral { AZ_CLASS_ALLOCATOR_IMPL(EditorTubeShapeComponentMode, AZ::SystemAllocator, 0) - static const AZ::Crc32 s_resetVariableRadii = AZ_CRC("com.amazon.action.tubeshape.reset_radii", 0x0f2ef8e2); + static const AZ::Crc32 s_resetVariableRadii = AZ_CRC("com.o3de.action.tubeshape.reset_radii", 0x0f2ef8e2); static const char* const s_resetRadiiTitle = "Reset Radii"; static const char* const s_resetRadiiDesc = "Reset all variable radius values to the default"; diff --git a/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp b/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp index c084cfa6e0..9624338f5d 100644 --- a/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp +++ b/Gems/PhysX/Code/Editor/ColliderComponentMode.cpp @@ -28,10 +28,10 @@ namespace PhysX namespace { //! Uri's for shortcut actions. - const AZ::Crc32 SetDimensionsSubModeActionUri = AZ_CRC("com.amazon.action.physx.setdimensionssubmode", 0x77b70dd6); - const AZ::Crc32 SetOffsetSubModeActionUri = AZ_CRC("com.amazon.action.physx.setoffsetsubmode", 0xc06132e5); - const AZ::Crc32 SetRotationSubModeActionUri = AZ_CRC("com.amazon.action.physx.setrotationsubmode", 0xc4225918); - const AZ::Crc32 ResetSubModeActionUri = AZ_CRC("com.amazon.action.physx.resetsubmode", 0xb70b120e); + const AZ::Crc32 SetDimensionsSubModeActionUri = AZ_CRC("com.o3de.action.physx.setdimensionssubmode", 0x77b70dd6); + const AZ::Crc32 SetOffsetSubModeActionUri = AZ_CRC("com.o3de.action.physx.setoffsetsubmode", 0xc06132e5); + const AZ::Crc32 SetRotationSubModeActionUri = AZ_CRC("com.o3de.action.physx.setrotationsubmode", 0xc4225918); + const AZ::Crc32 ResetSubModeActionUri = AZ_CRC("com.o3de.action.physx.resetsubmode", 0xb70b120e); } AZ_CLASS_ALLOCATOR_IMPL(ColliderComponentMode, AZ::SystemAllocator, 0); diff --git a/Gems/PhysX/Code/Editor/EditorJointComponentMode.cpp b/Gems/PhysX/Code/Editor/EditorJointComponentMode.cpp index 4da6e8b892..27feae137c 100644 --- a/Gems/PhysX/Code/Editor/EditorJointComponentMode.cpp +++ b/Gems/PhysX/Code/Editor/EditorJointComponentMode.cpp @@ -23,8 +23,8 @@ namespace PhysX namespace { //! Uri's for shortcut actions. - const AZ::Crc32 GoToNextModeActionUri = AZ_CRC("com.amazon.action.physx.joint.nextmode", 0xe9cf4ed6); - const AZ::Crc32 GoToPrevModeActionUri = AZ_CRC("com.amazon.action.physx.joint.prevmode", 0xe70f8daa); + const AZ::Crc32 GoToNextModeActionUri = AZ_CRC("com.o3de.action.physx.joint.nextmode", 0xe9cf4ed6); + const AZ::Crc32 GoToPrevModeActionUri = AZ_CRC("com.o3de.action.physx.joint.prevmode", 0xe70f8daa); } const AZStd::string EditorJointComponentMode::s_parameterAngularPair = "Twist Limits"; diff --git a/Gems/WhiteBox/Code/Source/SubComponentModes/EditorWhiteBoxDefaultMode.cpp b/Gems/WhiteBox/Code/Source/SubComponentModes/EditorWhiteBoxDefaultMode.cpp index e9b5514006..b1f26e2e2e 100644 --- a/Gems/WhiteBox/Code/Source/SubComponentModes/EditorWhiteBoxDefaultMode.cpp +++ b/Gems/WhiteBox/Code/Source/SubComponentModes/EditorWhiteBoxDefaultMode.cpp @@ -34,8 +34,8 @@ namespace WhiteBox AZ::Color, cl_whiteBoxVertexIndicatorColor, AZ::Color::CreateFromRgba(0, 0, 0, 102), nullptr, AZ::ConsoleFunctorFlags::Null, "The color of the vertex indicator"); - static const AZ::Crc32 HideEdge = AZ_CRC("com.amazon.action.whitebox.hide_edge", 0x6a60ae23); - static const AZ::Crc32 HideVertex = AZ_CRC("com.amazon.action.whitebox.hide_vertex", 0x4a4bd092); + static const AZ::Crc32 HideEdge = AZ_CRC("com.o3de.action.whitebox.hide_edge", 0x6a60ae23); + static const AZ::Crc32 HideVertex = AZ_CRC("com.o3de.action.whitebox.hide_vertex", 0x4a4bd092); static const char* const HideEdgeTitle = "Hide Edge"; static const char* const HideEdgeDesc = "Hide the selected edge to merge the two connected polygons"; From a48a0d1f8a2470a8fa219d9f681a34c67e8925d1 Mon Sep 17 00:00:00 2001 From: puvvadar Date: Mon, 12 Jul 2021 11:15:38 -0700 Subject: [PATCH 13/53] Fix positional desync of network objects plus related log spam Signed-off-by: puvvadar --- .../TcpTransport/TcpSocketManager_Select.cpp | 2 +- .../Editor/MultiplayerEditorConnection.cpp | 14 ++++++++++- .../Code/Source/MultiplayerSystemComponent.h | 2 +- .../EntityReplication/PropertyPublisher.cpp | 25 +++++++++++-------- .../EntityReplication/ReplicationRecord.cpp | 2 ++ 5 files changed, 31 insertions(+), 14 deletions(-) diff --git a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocketManager_Select.cpp b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocketManager_Select.cpp index 130739ca39..651eff820e 100644 --- a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocketManager_Select.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocketManager_Select.cpp @@ -41,7 +41,7 @@ namespace AzNetworking void TcpSocketManager::ProcessEvents(AZ::TimeMs maxBlockMs, const SocketEventCallback& readCallback, const SocketEventCallback& writeCallback) { - if(static_cast(m_maxFd) <= 0 && m_socketFds.empty()) + if(static_cast(m_maxFd) <= 0 || m_socketFds.empty()) { // There are no available sockets to process return; diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp index 421d9875bc..bf4fd81ef1 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp @@ -178,6 +178,18 @@ namespace Multiplayer void MultiplayerEditorConnection::OnDisconnect([[maybe_unused]] AzNetworking::IConnection* connection, [[maybe_unused]] DisconnectReason reason, [[maybe_unused]] TerminationEndpoint endpoint) { - ; + bool editorLaunch = false; + if (auto console = AZ::Interface::Get(); console) + { + console->GetCvarValue("editorsv_launch", editorLaunch); + } + + if (editorsv_isDedicated && editorLaunch && m_networkEditorInterface->GetConnectionSet().GetConnectionCount() == 1) + { + if (m_networkEditorInterface->GetPort() != 0) + { + m_networkEditorInterface->StopListening(); + } + } } } diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h index aae363f0d2..7977a39443 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h @@ -151,7 +151,7 @@ namespace Multiplayer AZStd::queue m_pendingConnectionTickets; AZ::TimeMs m_lastReplicatedHostTimeMs = AZ::TimeMs{ 0 }; - HostFrameId m_lastReplicatedHostFrameId = InvalidHostFrameId; + HostFrameId m_lastReplicatedHostFrameId = HostFrameId(0); double m_serverSendAccumulator = 0.0; float m_renderBlendFactor = 0.0f; diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.cpp index 2272f43a08..1b21dca50a 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.cpp @@ -123,20 +123,23 @@ namespace Multiplayer bool PropertyPublisher::PrepareUpdateEntityRecord() { - // If we reach the maximum outstanding records, reset the replication state + bool didPrepare = true; if (m_sentRecords.size() >= net_EntityReplicatorRecordsMax) { - return PrepareAddEntityRecord(); + // If we reach the maximum outstanding records, reset the replication state + didPrepare = PrepareAddEntityRecord(); } - - // We need to clear out old records, and build up a list of everything that has changed since the last acked packet - m_sentRecords.push_front(m_pendingRecord); - auto iter = m_sentRecords.begin(); - ++iter; // Consider everything after the record we are going to send - for (; iter != m_sentRecords.end(); ++iter) + else { - // Sequence wasn't acked, so we need to send these bits again - m_pendingRecord.Append(*iter); + // We need to clear out old records, and build up a list of everything that has changed since the last acked packet + m_sentRecords.push_front(m_pendingRecord); + auto iter = m_sentRecords.begin(); + ++iter; // Consider everything after the record we are going to send + for (; iter != m_sentRecords.end(); ++iter) + { + // Sequence wasn't acked, so we need to send these bits again + m_pendingRecord.Append(*iter); + } } // Don't send predictable properties back to the Autonomous unless we correct them @@ -145,7 +148,7 @@ namespace Multiplayer m_pendingRecord.Subtract(m_netBindComponent->GetPredictableRecord()); } - return true; + return didPrepare; } bool PropertyPublisher::PrepareDeleteEntityRecord() diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp index eecd4915e7..1c59c70867 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp @@ -191,6 +191,8 @@ namespace Multiplayer bool ReplicationRecord::ContainsAuthorityToClientBits() const { + // Check != Authority here since several modes require information about client updates + // (i.e. Autonomous when performing corrections) return (m_remoteNetEntityRole != NetEntityRole::Authority) || (m_remoteNetEntityRole == NetEntityRole::InvalidRole); } From b7e3db9d82fa4ea76d88eade06163af2e6cdc6b2 Mon Sep 17 00:00:00 2001 From: srikappa Date: Mon, 12 Jul 2021 11:58:14 -0700 Subject: [PATCH 14/53] Make prefab patch application use a best effort mechanism Signed-off-by: srikappa --- .../AzCore/Serialization/Json/JsonMerger.cpp | 10 +++- .../Serialization/Json/TestCases_Patching.cpp | 52 ++++++++++++++++++- .../Instance/InstanceToTemplatePropagator.cpp | 19 ++++--- .../AzToolsFramework/Prefab/Link/Link.cpp | 23 ++++++-- .../Prefab/PrefabDomUtils.cpp | 20 +++++++ .../AzToolsFramework/Prefab/PrefabDomUtils.h | 6 +++ .../AzToolsFramework/Prefab/PrefabUndo.cpp | 9 +++- .../Tests/Prefab/PrefabUndoLinkTests.cpp | 4 +- 8 files changed, 123 insertions(+), 20 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp index 61869b7eb5..51e47840c9 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp @@ -110,7 +110,15 @@ namespace AZ if (result.GetProcessing() == Processing::Halted) { - return result; + ResultCode reportedResult = settings.m_reporting(R"(One of the patches couldn't be applied correctly.)", result, element); + if (reportedResult.GetOutcome() == Outcomes::PartialSkip) + { + result = reportedResult; + } + else + { + return result; + } } } diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Patching.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Patching.cpp index ae2dea4e48..046bb88d76 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Patching.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Patching.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include @@ -43,7 +44,9 @@ namespace JsonSerializationTests } void CheckApplyPatchOutcome(const char* target, const char* patch, - AZ::JsonSerializationResult::Outcomes outcome, AZ::JsonSerializationResult::Processing processing) + AZ::JsonSerializationResult::Outcomes outcome, + AZ::JsonSerializationResult::Processing processing, + const AZ::JsonApplyPatchSettings& settings = AZ::JsonApplyPatchSettings{}) { m_jsonDocument->Parse(target); ASSERT_FALSE(m_jsonDocument->HasParseError()); @@ -53,12 +56,27 @@ namespace JsonSerializationTests ASSERT_FALSE(patchDocument.HasParseError()); AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(*m_jsonDocument, - m_jsonDocument->GetAllocator(), patchDocument, AZ::JsonMergeApproach::JsonPatch); + m_jsonDocument->GetAllocator(), patchDocument, AZ::JsonMergeApproach::JsonPatch, settings); EXPECT_EQ(result.GetTask(), AZ::JsonSerializationResult::Tasks::Merge); EXPECT_EQ(result.GetOutcome(), outcome); EXPECT_EQ(result.GetProcessing(), processing); } + void CheckApplyPatchOutcome( + const char* target, + const char* patch, + const char* expectedPatchedResult, + AZ::JsonSerializationResult::Outcomes outcome, + AZ::JsonSerializationResult::Processing processing, + const AZ::JsonApplyPatchSettings& settings = AZ::JsonApplyPatchSettings{}) + { + CheckApplyPatchOutcome(target, patch, outcome, processing, settings); + rapidjson::Document expectedPatchedDocument; + expectedPatchedDocument.Parse(expectedPatchedResult); + ASSERT_FALSE(expectedPatchedDocument.HasParseError()); + EXPECT_EQ(AZ::JsonSerialization::Compare(expectedPatchedDocument, *m_jsonDocument), AZ::JsonSerializerCompareResult::Equal); + } + void CheckCreatePatch_Core(const char* source, AZStd::string_view patch, const char* target, AZ::JsonMergeApproach approach) { @@ -262,6 +280,36 @@ namespace JsonSerializationTests Outcomes::TypeMismatch, Processing::Halted); } + TEST_F(JsonPatchingSerializationTests, ApplyPatch_UseJsonPatchWithCustomReportingCallback_ReportPartialSkip) + { + using namespace AZ::JsonSerializationResult; + auto issueReportingCallback = [](AZStd::string_view, AZ::JsonSerializationResult::ResultCode result, + AZStd::string_view) -> AZ::JsonSerializationResult::ResultCode + { + using namespace AZ::JsonSerializationResult; + if (result.GetProcessing() == Processing::Halted) + { + return ResultCode(result.GetTask(), Outcomes::PartialSkip); + } + return result; + }; + + AZ::JsonApplyPatchSettings applyPatchSettings; + applyPatchSettings.m_reporting = AZStd::move(issueReportingCallback); + CheckApplyPatchOutcome( + R"({})", + R"([ + { "op": "add", "path": "/nonexistent_key/new_member", "value": "someValue" }, + { "op": "add", "path": "/test", "value": "someValue" } + ])", + R"( + { "test": "someValue" } + )", + Outcomes::PartialSkip, + Processing::Completed, + AZStd::move(applyPatchSettings)); + } + TEST_F(JsonPatchingSerializationTests, ApplyPatch_UseJsonPatchAddUnnamedMember_ReportsSuccess) { CheckApplyPatch( diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp index 720c14ed36..03d4b14190 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Instance/InstanceToTemplatePropagator.cpp @@ -172,20 +172,23 @@ namespace AzToolsFramework PrefabDom& templateDomReference = m_prefabSystemComponentInterface->FindTemplateDom(templateId); //apply patch to template - AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(templateDomReference, - templateDomReference.GetAllocator(), providedPatch, AZ::JsonMergeApproach::JsonPatch); + AZ::JsonSerializationResult::ResultCode result = + PrefabDomUtils::ApplyPatches(templateDomReference, templateDomReference.GetAllocator(), providedPatch); //trigger propagation - if (result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success) + if (result.GetOutcome() != AZ::JsonSerializationResult::Outcomes::Success) { - m_prefabSystemComponentInterface->SetTemplateDirtyFlag(templateId, true); - m_prefabSystemComponentInterface->PropagateTemplateChanges(templateId, instanceToExclude); - return true; + AZ_Error("Prefab", false, "Patch was not successfully applied."); + return false; } else { - AZ_Error("Prefab", false, "Patch was not successfully applied"); - return false; + AZ_Error( + "Prefab", result.GetOutcome() != AZ::JsonSerializationResult::Outcomes::PartialSkip, + "Some of the patches are not successfully applied."); + m_prefabSystemComponentInterface->SetTemplateDirtyFlag(templateId, true); + m_prefabSystemComponentInterface->PropagateTemplateChanges(templateId, instanceToExclude); + return true; } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Link/Link.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Link/Link.cpp index 1d27fa6375..333c3f2dbc 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Link/Link.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/Link/Link.cpp @@ -176,12 +176,17 @@ namespace AzToolsFramework } else { - AZ::JsonSerializationResult::ResultCode applyPatchResult = AZ::JsonSerialization::ApplyPatch( - sourceTemplateDomCopy, - targetTemplatePrefabDom.GetAllocator(), - patchesReference->get(), - AZ::JsonMergeApproach::JsonPatch); + AZ::JsonSerializationResult::ResultCode applyPatchResult = + PrefabDomUtils::ApplyPatches(sourceTemplateDomCopy, targetTemplatePrefabDom.GetAllocator(), patchesReference->get()); linkedInstanceDom.CopyFrom(sourceTemplateDomCopy, targetTemplatePrefabDom.GetAllocator()); + + PrefabDomValueReference sourceTemplateName = + PrefabDomUtils::FindPrefabDomValue(sourceTemplateDomCopy, PrefabDomUtils::SourceName); + AZ_Assert(sourceTemplateName && sourceTemplateName->get().IsString(), "A valid source template name couldn't be found"); + PrefabDomValueReference targetTemplateName = + PrefabDomUtils::FindPrefabDomValue(targetTemplatePrefabDom, PrefabDomUtils::SourceName); + AZ_Assert(targetTemplateName && targetTemplateName->get().IsString(), "A valid target template name couldn't be found"); + if (applyPatchResult.GetProcessing() != AZ::JsonSerializationResult::Processing::Completed) { AZ_Error( @@ -190,6 +195,14 @@ namespace AzToolsFramework m_sourceTemplateId, m_targetTemplateId); return false; } + if (applyPatchResult.GetOutcome() == AZ::JsonSerializationResult::Outcomes::PartialSkip) + { + AZ_Error( + "Prefab", false, + "Link::UpdateTarget - Some of the patches couldn't be applied on the source template '%s' present under the " + "target Template '%s'.", + sourceTemplateName->get().GetString(), targetTemplateName->get().GetString()); + } } // This is a guardrail to ensure the linked instance dom always has the LinkId value diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp index bac63d94b4..86137ae547 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp @@ -236,6 +236,26 @@ namespace AzToolsFramework return findInstancesResult->get(); } + AZ::JsonSerializationResult::ResultCode ApplyPatches( + PrefabDomValue& prefabDomToApplyPatchesOn, PrefabDom::AllocatorType& allocator, const PrefabDomValue& patches) + { + auto issueReportingCallback = [](AZStd::string_view, AZ::JsonSerializationResult::ResultCode result, + AZStd::string_view) -> AZ::JsonSerializationResult::ResultCode + { + using namespace AZ::JsonSerializationResult; + if (result.GetProcessing() == Processing::Halted) + { + return ResultCode(result.GetTask(), Outcomes::PartialSkip); + } + return result; + }; + + AZ::JsonApplyPatchSettings applyPatchSettings; + applyPatchSettings.m_reporting = AZStd::move(issueReportingCallback); + return AZ::JsonSerialization::ApplyPatch( + prefabDomToApplyPatchesOn, allocator, patches, AZ::JsonMergeApproach::JsonPatch, applyPatchSettings); + } + void PrintPrefabDomValue( [[maybe_unused]] const AZStd::string_view printMessage, [[maybe_unused]] const PrefabDomValue& prefabDomValue) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h index 709461022e..4d4b7a3e32 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.h @@ -7,6 +7,7 @@ #pragma once +#include #include #include #include @@ -122,6 +123,11 @@ namespace AzToolsFramework */ PrefabDomValueConstReference GetInstancesValue(const PrefabDomValue& prefabDom); + AZ::JsonSerializationResult::ResultCode ApplyPatches( + PrefabDomValue& prefabDomToApplyPatchesOn, + PrefabDom::AllocatorType& allocator, + const PrefabDomValue& patches); + /** * Prints the contents of the given prefab DOM value to the debug output console in a readable format. * @param printMessage The message that will be printed before printing the PrefabDomValue diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp index e29c33a21f..728b95f74b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp @@ -261,8 +261,13 @@ namespace AzToolsFramework instanceDom.CopyFrom(instanceDomRef->get(), instanceDom.GetAllocator()); //apply the patch to the template within the target - AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(instanceDom, - instanceDom.GetAllocator(), patch, AZ::JsonMergeApproach::JsonPatch); + AZ::JsonSerializationResult::ResultCode result = PrefabDomUtils::ApplyPatches(instanceDom, instanceDom.GetAllocator(), patch); + + AZ_Error( + "Prefab", + result.GetOutcome() != AZ::JsonSerializationResult::Outcomes::PartialSkip && + result.GetOutcome() != AZ::JsonSerializationResult::Outcomes::Success, + "Some of the patches are not successfully applied."); //remove the link id placed into the instance auto linkIdIter = instanceDom.FindMember(PrefabDomUtils::LinkIdName); diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoLinkTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoLinkTests.cpp index cdc5faaef0..253671189d 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoLinkTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabUndoLinkTests.cpp @@ -96,8 +96,8 @@ namespace UnitTest //apply the patch PrefabDom& templateDomReference = m_prefabSystemComponent->FindTemplateDom(nestedTemplateId); - AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::ApplyPatch(templateDomReference, - templateDomReference.GetAllocator(), patch, AZ::JsonMergeApproach::JsonPatch); + AZ::JsonSerializationResult::ResultCode result = + PrefabDomUtils::ApplyPatches(templateDomReference, templateDomReference.GetAllocator(), patch); AZ_Error("Prefab", result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success, "Patch was not successfully applied"); From 6d2fbacda51372fd4c482f28a100be569c6da798 Mon Sep 17 00:00:00 2001 From: scspaldi Date: Mon, 12 Jul 2021 13:43:41 -0700 Subject: [PATCH 15/53] Added Lua Editor window to kill process list. Signed-off-by: scspaldi --- Tools/LyTestTools/ly_test_tools/o3de/asset_processor_utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Tools/LyTestTools/ly_test_tools/o3de/asset_processor_utils.py b/Tools/LyTestTools/ly_test_tools/o3de/asset_processor_utils.py index 2b6ff8292e..d108140977 100644 --- a/Tools/LyTestTools/ly_test_tools/o3de/asset_processor_utils.py +++ b/Tools/LyTestTools/ly_test_tools/o3de/asset_processor_utils.py @@ -45,4 +45,5 @@ def kill_asset_processor(): kill_processes_named('AssetProcessorBatch', ignore_extensions=True) kill_processes_named('AssetBuilder', ignore_extensions=True) kill_processes_named('rc', ignore_extensions=True) + kill_processes_named('Lua Editor', ignore_extensions=True) From c494adba885c5624d9bbb829e115c9004fc95ac1 Mon Sep 17 00:00:00 2001 From: srikappa Date: Mon, 12 Jul 2021 14:21:04 -0700 Subject: [PATCH 16/53] Use a utility function to compare json document and expected string Signed-off-by: srikappa --- .../AzCore/Tests/Serialization/Json/TestCases_Patching.cpp | 5 +---- .../AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Patching.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Patching.cpp index 046bb88d76..15c3c8f71b 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Patching.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Patching.cpp @@ -71,10 +71,7 @@ namespace JsonSerializationTests const AZ::JsonApplyPatchSettings& settings = AZ::JsonApplyPatchSettings{}) { CheckApplyPatchOutcome(target, patch, outcome, processing, settings); - rapidjson::Document expectedPatchedDocument; - expectedPatchedDocument.Parse(expectedPatchedResult); - ASSERT_FALSE(expectedPatchedDocument.HasParseError()); - EXPECT_EQ(AZ::JsonSerialization::Compare(expectedPatchedDocument, *m_jsonDocument), AZ::JsonSerializerCompareResult::Equal); + Expect_DocStrEq(expectedPatchedResult); } void CheckCreatePatch_Core(const char* source, AZStd::string_view patch, const char* target, diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp index 728b95f74b..7d9fb64c96 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndo.cpp @@ -265,8 +265,8 @@ namespace AzToolsFramework AZ_Error( "Prefab", - result.GetOutcome() != AZ::JsonSerializationResult::Outcomes::PartialSkip && - result.GetOutcome() != AZ::JsonSerializationResult::Outcomes::Success, + result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::PartialSkip || + result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success, "Some of the patches are not successfully applied."); //remove the link id placed into the instance From 86a6d75b40362b287cf8e7dbe28c14f98aa17f2b Mon Sep 17 00:00:00 2001 From: srikappa Date: Mon, 12 Jul 2021 15:01:11 -0700 Subject: [PATCH 17/53] Remove an additional check during patch application to report errors Signed-off-by: srikappa --- .../AzCore/AzCore/Serialization/Json/JsonMerger.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp index 51e47840c9..61869b7eb5 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp @@ -110,15 +110,7 @@ namespace AZ if (result.GetProcessing() == Processing::Halted) { - ResultCode reportedResult = settings.m_reporting(R"(One of the patches couldn't be applied correctly.)", result, element); - if (reportedResult.GetOutcome() == Outcomes::PartialSkip) - { - result = reportedResult; - } - else - { - return result; - } + return result; } } From 12a8cc7cd75edabb235086e92be2ab93eb673117 Mon Sep 17 00:00:00 2001 From: evanchia Date: Mon, 12 Jul 2021 15:31:09 -0700 Subject: [PATCH 18/53] Removing deleted test from CMakeLists and updated in line comments for sample test Signed-off-by: evanchia --- Tools/LyTestTools/tests/CMakeLists.txt | 14 ---------- Tools/LyTestTools/tests/integ/sanity_tests.py | 26 +++++++++++++++++++ 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/Tools/LyTestTools/tests/CMakeLists.txt b/Tools/LyTestTools/tests/CMakeLists.txt index e5f270197c..5e57cbf123 100644 --- a/Tools/LyTestTools/tests/CMakeLists.txt +++ b/Tools/LyTestTools/tests/CMakeLists.txt @@ -52,18 +52,4 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED AND AutomatedT AutomatedTesting.Assets COMPONENT TestTools ) - - # Example tests. - ly_add_pytest( - NAME LyTestTools_ExampleTests_periodic_no_gpu - PATH ${CMAKE_CURRENT_LIST_DIR}/example/test_system_example.py - TEST_SERIAL - TEST_SUITE periodic - RUNTIME_DEPENDENCIES - Legacy::Editor - AssetProcessor - AutomatedTesting.GameLauncher - AutomatedTesting.Assets - COMPONENT TestTools - ) endif() diff --git a/Tools/LyTestTools/tests/integ/sanity_tests.py b/Tools/LyTestTools/tests/integ/sanity_tests.py index 0aacfff8c6..f68bc9ae57 100755 --- a/Tools/LyTestTools/tests/integ/sanity_tests.py +++ b/Tools/LyTestTools/tests/integ/sanity_tests.py @@ -6,24 +6,43 @@ SPDX-License-Identifier: Apache-2.0 OR MIT A sanity test for the built-in fixtures. Launch the windows launcher attached to the currently installed instance. """ +# Import any dependencies for the test. import logging import pytest +# Import any desired LTT modules from the package `ly_test_tools`. All LTT modules can be viewed at `Tools/LyTestTools/ly_test_tools`. import ly_test_tools +# The `launchers.launcher_helper` module helps create Launcher objects which control the Open 3D Engine (O3DE) Editor and game clients. import ly_test_tools.launchers.launcher_helper as launcher_helper +# The `builtin.helpers` module helps create the Workspace object, which controls the testing workspace in LTT. import ly_test_tools.builtin.helpers as helpers +# The `environment` module contains tools that involve the system's environment such as processes or timed waiters. import ly_test_tools.environment.process_utils as process_utils import ly_test_tools.environment.waiter as waiter +# Initialize a logger instance to hook all test logs together. The sub-logger pattern below makes it easy to track which file creates a log line. logger = logging.getLogger(__name__) # Note: For device testing, device ids must exist in ~/ly_test_tools/devices.ini, see README.txt for more info. +# First define the class `TestAutomatedTestingProject` to group test functions together. +# The example test contains two test functions: `test_StartGameLauncher_Sanity` and `test_StartEditor_Sanity`. @pytest.mark.parametrize("project", ["AutomatedTesting"]) +# The example test utilizes Pytest parameterization. The following sets the `project` parameter to `AutomatedTesting` +# for both test functions. Notice that the Pytest mark is defined at the class level to affect both test functions. class TestAutomatedTestingProject(object): def test_StartGameLauncher_Sanity(self, project): + """ + The `test_StartGameLauncher_Sanity` test function verifies that the O3DE game client launches successfully. + Start the test by utilizing the `kill_processes_named` function to close any open O3DE processes that may + interfere with the test. The Workspace object emulates the O3DE package by locating the engine and project + directories. The Launcher object controls the O3DE game client and requires a Workspace object for + initialization. Add the `-rhi=Null` arg to the executable call to disable GPU rendering. This allows the + test to run on instances without a GPU. We launch the game client executable and wait for the process to exist. + A try/finally block ensures proper test cleanup if issues occur during the test. + """ # Kill processes that may interfere with the test process_utils.kill_processes_named(names=process_utils.LY_PROCESS_KILL_LIST, ignore_extensions=True) @@ -45,6 +64,13 @@ class TestAutomatedTestingProject(object): @pytest.mark.skipif(not ly_test_tools.WINDOWS, reason="Editor currently only functions on Windows") def test_StartEditor_Sanity(self, project): + """ + The `test_StartEditor_Sanity` test function is similar to the previous example with minor adjustments. A + PyTest mark skips the test if the operating system is not Windows. We use the `create_editor` function instead + of `create_launcher` to create an Editor type launcher instead of a game client type launcher. The additional + `-autotest_mode` arg supresses modal dialogs from interfering with our test. We launch the Editor executable and + wait for the process to exist. + """ # Kill processes that may interfere with the test process_utils.kill_processes_named(names=process_utils.LY_PROCESS_KILL_LIST, ignore_extensions=True) From afd97abdcfc08b463e248ba4a035fc2d4c3ad470 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Fri, 9 Jul 2021 08:07:47 -0700 Subject: [PATCH 19/53] Move files to AzFramework/Test and AzToolsFramework/Test accordingly Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- Code/Framework/{ => AzFramework}/Tests/Application.cpp | 0 .../Framework/{ => AzFramework}/Tests/ArchiveCompressionTests.cpp | 0 Code/Framework/{ => AzFramework}/Tests/ArchiveTests.cpp | 0 Code/Framework/{ => AzFramework}/Tests/AssetCatalog.cpp | 0 .../{ => AzFramework}/Tests/AssetProcessorConnection.cpp | 0 Code/Framework/{ => AzFramework}/Tests/BehaviorEntityTests.cpp | 0 Code/Framework/{ => AzFramework}/Tests/BinToTextEncode.cpp | 0 Code/Framework/{ => AzFramework}/Tests/CMakeLists.txt | 0 Code/Framework/{ => AzFramework}/Tests/CameraInputTests.cpp | 0 Code/Framework/{ => AzFramework}/Tests/CameraState.cpp | 0 Code/Framework/{ => AzFramework}/Tests/ClickDetectorTests.cpp | 0 Code/Framework/{ => AzFramework}/Tests/CursorStateTests.cpp | 0 Code/Framework/{ => AzFramework}/Tests/EntityContext.cpp | 0 Code/Framework/{ => AzFramework}/Tests/FileIO.cpp | 0 Code/Framework/{ => AzFramework}/Tests/FileTagTests.cpp | 0 .../{ => AzFramework}/Tests/FrameworkApplicationFixture.h | 0 Code/Framework/{ => AzFramework}/Tests/GenAppDescriptors.cpp | 0 Code/Framework/{ => AzFramework}/Tests/InputTests.cpp | 0 .../Tests/Mocks/MockSpawnableEntitiesInterface.h | 0 Code/Framework/{ => AzFramework}/Tests/NativeWindow.cpp | 0 Code/Framework/{ => AzFramework}/Tests/OctreePerformanceTests.cpp | 0 Code/Framework/{ => AzFramework}/Tests/OctreeTests.cpp | 0 .../Tests/Platform/Android/AzFrameworkTests_Traits_Android.h | 0 .../Tests/Platform/Android/AzFrameworkTests_Traits_Platform.h | 0 .../Tests/Platform/Android/platform_android_files.cmake | 0 .../Tests/Platform/Linux/AzFrameworkTests_Traits_Linux.h | 0 .../Tests/Platform/Linux/AzFrameworkTests_Traits_Platform.h | 0 .../Tests/Platform/Linux/platform_linux_files.cmake | 0 .../Tests/Platform/Mac/AzFrameworkTests_Traits_Mac.h | 0 .../Tests/Platform/Mac/AzFrameworkTests_Traits_Platform.h | 0 .../{ => AzFramework}/Tests/Platform/Mac/platform_mac_files.cmake | 0 .../Tests/Platform/Windows/AzFrameworkTests_Traits_Platform.h | 0 .../Tests/Platform/Windows/AzFrameworkTests_Traits_Windows.h | 0 .../Tests/Platform/Windows/platform_windows_files.cmake | 0 .../Tests/Platform/iOS/AzFrameworkTests_Traits_Platform.h | 0 .../Tests/Platform/iOS/AzFrameworkTests_Traits_iOS.h | 0 .../{ => AzFramework}/Tests/Platform/iOS/platform_ios_files.cmake | 0 Code/Framework/{ => AzFramework}/Tests/PlatformHelper.cpp | 0 Code/Framework/{ => AzFramework}/Tests/ProcessLaunchMain.cpp | 0 .../Framework/{ => AzFramework}/Tests/ProcessLaunchParseTests.cpp | 0 Code/Framework/{ => AzFramework}/Tests/Scene.cpp | 0 .../Tests/Spawnable/SpawnableEntitiesManagerTests.cpp | 0 Code/Framework/{ => AzFramework}/Tests/Utils/Utils.cpp | 0 Code/Framework/{ => AzFramework}/Tests/Utils/Utils.h | 0 .../{ => AzFramework}/Tests/framework_shared_tests_files.cmake | 0 Code/Framework/{ => AzFramework}/Tests/frameworktests_files.cmake | 0 .../{ => AzFramework}/Tests/process_launch_test_files.cmake | 0 .../{ => AzToolsFramework}/Tests/ComponentAdapterTests.cpp | 0 .../Framework/{ => AzToolsFramework}/Tests/ComponentAddRemove.cpp | 0 .../EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp | 0 .../EntityOwnershipService/EntityOwnershipServiceTestFixture.h | 0 .../EntityOwnershipService/SliceEditorEntityOwnershipTests.cpp | 0 .../Tests/EntityOwnershipService/SliceEntityOwnershipTests.cpp | 0 Code/Framework/{ => AzToolsFramework}/Tests/EntityTestbed.h | 0 Code/Framework/{ => AzToolsFramework}/Tests/FileFunc.cpp | 0 .../{ => AzToolsFramework}/Tests/GenericComponentWrapperTest.cpp | 0 .../{ => AzToolsFramework}/Tests/InstanceDataHierarchy.cpp | 0 .../{ => AzToolsFramework}/Tests/SQLiteConnectionTests.cpp | 0 .../{ => AzToolsFramework}/Tests/Script/ScriptComponentTests.cpp | 0 .../{ => AzToolsFramework}/Tests/Script/ScriptEntityTests.cpp | 0 Code/Framework/{ => AzToolsFramework}/Tests/Slices.cpp | 0 .../Framework/{ => AzToolsFramework}/Tests/TransformComponent.cpp | 0 62 files changed, 0 insertions(+), 0 deletions(-) rename Code/Framework/{ => AzFramework}/Tests/Application.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/ArchiveCompressionTests.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/ArchiveTests.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/AssetCatalog.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/AssetProcessorConnection.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/BehaviorEntityTests.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/BinToTextEncode.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/CMakeLists.txt (100%) rename Code/Framework/{ => AzFramework}/Tests/CameraInputTests.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/CameraState.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/ClickDetectorTests.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/CursorStateTests.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/EntityContext.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/FileIO.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/FileTagTests.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/FrameworkApplicationFixture.h (100%) rename Code/Framework/{ => AzFramework}/Tests/GenAppDescriptors.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/InputTests.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/Mocks/MockSpawnableEntitiesInterface.h (100%) rename Code/Framework/{ => AzFramework}/Tests/NativeWindow.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/OctreePerformanceTests.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/OctreeTests.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/Platform/Android/AzFrameworkTests_Traits_Android.h (100%) rename Code/Framework/{ => AzFramework}/Tests/Platform/Android/AzFrameworkTests_Traits_Platform.h (100%) rename Code/Framework/{ => AzFramework}/Tests/Platform/Android/platform_android_files.cmake (100%) rename Code/Framework/{ => AzFramework}/Tests/Platform/Linux/AzFrameworkTests_Traits_Linux.h (100%) rename Code/Framework/{ => AzFramework}/Tests/Platform/Linux/AzFrameworkTests_Traits_Platform.h (100%) rename Code/Framework/{ => AzFramework}/Tests/Platform/Linux/platform_linux_files.cmake (100%) rename Code/Framework/{ => AzFramework}/Tests/Platform/Mac/AzFrameworkTests_Traits_Mac.h (100%) rename Code/Framework/{ => AzFramework}/Tests/Platform/Mac/AzFrameworkTests_Traits_Platform.h (100%) rename Code/Framework/{ => AzFramework}/Tests/Platform/Mac/platform_mac_files.cmake (100%) rename Code/Framework/{ => AzFramework}/Tests/Platform/Windows/AzFrameworkTests_Traits_Platform.h (100%) rename Code/Framework/{ => AzFramework}/Tests/Platform/Windows/AzFrameworkTests_Traits_Windows.h (100%) rename Code/Framework/{ => AzFramework}/Tests/Platform/Windows/platform_windows_files.cmake (100%) rename Code/Framework/{ => AzFramework}/Tests/Platform/iOS/AzFrameworkTests_Traits_Platform.h (100%) rename Code/Framework/{ => AzFramework}/Tests/Platform/iOS/AzFrameworkTests_Traits_iOS.h (100%) rename Code/Framework/{ => AzFramework}/Tests/Platform/iOS/platform_ios_files.cmake (100%) rename Code/Framework/{ => AzFramework}/Tests/PlatformHelper.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/ProcessLaunchMain.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/ProcessLaunchParseTests.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/Scene.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/Utils/Utils.cpp (100%) rename Code/Framework/{ => AzFramework}/Tests/Utils/Utils.h (100%) rename Code/Framework/{ => AzFramework}/Tests/framework_shared_tests_files.cmake (100%) rename Code/Framework/{ => AzFramework}/Tests/frameworktests_files.cmake (100%) rename Code/Framework/{ => AzFramework}/Tests/process_launch_test_files.cmake (100%) rename Code/Framework/{ => AzToolsFramework}/Tests/ComponentAdapterTests.cpp (100%) rename Code/Framework/{ => AzToolsFramework}/Tests/ComponentAddRemove.cpp (100%) rename Code/Framework/{ => AzToolsFramework}/Tests/EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp (100%) rename Code/Framework/{ => AzToolsFramework}/Tests/EntityOwnershipService/EntityOwnershipServiceTestFixture.h (100%) rename Code/Framework/{ => AzToolsFramework}/Tests/EntityOwnershipService/SliceEditorEntityOwnershipTests.cpp (100%) rename Code/Framework/{ => AzToolsFramework}/Tests/EntityOwnershipService/SliceEntityOwnershipTests.cpp (100%) rename Code/Framework/{ => AzToolsFramework}/Tests/EntityTestbed.h (100%) rename Code/Framework/{ => AzToolsFramework}/Tests/FileFunc.cpp (100%) rename Code/Framework/{ => AzToolsFramework}/Tests/GenericComponentWrapperTest.cpp (100%) rename Code/Framework/{ => AzToolsFramework}/Tests/InstanceDataHierarchy.cpp (100%) rename Code/Framework/{ => AzToolsFramework}/Tests/SQLiteConnectionTests.cpp (100%) rename Code/Framework/{ => AzToolsFramework}/Tests/Script/ScriptComponentTests.cpp (100%) rename Code/Framework/{ => AzToolsFramework}/Tests/Script/ScriptEntityTests.cpp (100%) rename Code/Framework/{ => AzToolsFramework}/Tests/Slices.cpp (100%) rename Code/Framework/{ => AzToolsFramework}/Tests/TransformComponent.cpp (100%) diff --git a/Code/Framework/Tests/Application.cpp b/Code/Framework/AzFramework/Tests/Application.cpp similarity index 100% rename from Code/Framework/Tests/Application.cpp rename to Code/Framework/AzFramework/Tests/Application.cpp diff --git a/Code/Framework/Tests/ArchiveCompressionTests.cpp b/Code/Framework/AzFramework/Tests/ArchiveCompressionTests.cpp similarity index 100% rename from Code/Framework/Tests/ArchiveCompressionTests.cpp rename to Code/Framework/AzFramework/Tests/ArchiveCompressionTests.cpp diff --git a/Code/Framework/Tests/ArchiveTests.cpp b/Code/Framework/AzFramework/Tests/ArchiveTests.cpp similarity index 100% rename from Code/Framework/Tests/ArchiveTests.cpp rename to Code/Framework/AzFramework/Tests/ArchiveTests.cpp diff --git a/Code/Framework/Tests/AssetCatalog.cpp b/Code/Framework/AzFramework/Tests/AssetCatalog.cpp similarity index 100% rename from Code/Framework/Tests/AssetCatalog.cpp rename to Code/Framework/AzFramework/Tests/AssetCatalog.cpp diff --git a/Code/Framework/Tests/AssetProcessorConnection.cpp b/Code/Framework/AzFramework/Tests/AssetProcessorConnection.cpp similarity index 100% rename from Code/Framework/Tests/AssetProcessorConnection.cpp rename to Code/Framework/AzFramework/Tests/AssetProcessorConnection.cpp diff --git a/Code/Framework/Tests/BehaviorEntityTests.cpp b/Code/Framework/AzFramework/Tests/BehaviorEntityTests.cpp similarity index 100% rename from Code/Framework/Tests/BehaviorEntityTests.cpp rename to Code/Framework/AzFramework/Tests/BehaviorEntityTests.cpp diff --git a/Code/Framework/Tests/BinToTextEncode.cpp b/Code/Framework/AzFramework/Tests/BinToTextEncode.cpp similarity index 100% rename from Code/Framework/Tests/BinToTextEncode.cpp rename to Code/Framework/AzFramework/Tests/BinToTextEncode.cpp diff --git a/Code/Framework/Tests/CMakeLists.txt b/Code/Framework/AzFramework/Tests/CMakeLists.txt similarity index 100% rename from Code/Framework/Tests/CMakeLists.txt rename to Code/Framework/AzFramework/Tests/CMakeLists.txt diff --git a/Code/Framework/Tests/CameraInputTests.cpp b/Code/Framework/AzFramework/Tests/CameraInputTests.cpp similarity index 100% rename from Code/Framework/Tests/CameraInputTests.cpp rename to Code/Framework/AzFramework/Tests/CameraInputTests.cpp diff --git a/Code/Framework/Tests/CameraState.cpp b/Code/Framework/AzFramework/Tests/CameraState.cpp similarity index 100% rename from Code/Framework/Tests/CameraState.cpp rename to Code/Framework/AzFramework/Tests/CameraState.cpp diff --git a/Code/Framework/Tests/ClickDetectorTests.cpp b/Code/Framework/AzFramework/Tests/ClickDetectorTests.cpp similarity index 100% rename from Code/Framework/Tests/ClickDetectorTests.cpp rename to Code/Framework/AzFramework/Tests/ClickDetectorTests.cpp diff --git a/Code/Framework/Tests/CursorStateTests.cpp b/Code/Framework/AzFramework/Tests/CursorStateTests.cpp similarity index 100% rename from Code/Framework/Tests/CursorStateTests.cpp rename to Code/Framework/AzFramework/Tests/CursorStateTests.cpp diff --git a/Code/Framework/Tests/EntityContext.cpp b/Code/Framework/AzFramework/Tests/EntityContext.cpp similarity index 100% rename from Code/Framework/Tests/EntityContext.cpp rename to Code/Framework/AzFramework/Tests/EntityContext.cpp diff --git a/Code/Framework/Tests/FileIO.cpp b/Code/Framework/AzFramework/Tests/FileIO.cpp similarity index 100% rename from Code/Framework/Tests/FileIO.cpp rename to Code/Framework/AzFramework/Tests/FileIO.cpp diff --git a/Code/Framework/Tests/FileTagTests.cpp b/Code/Framework/AzFramework/Tests/FileTagTests.cpp similarity index 100% rename from Code/Framework/Tests/FileTagTests.cpp rename to Code/Framework/AzFramework/Tests/FileTagTests.cpp diff --git a/Code/Framework/Tests/FrameworkApplicationFixture.h b/Code/Framework/AzFramework/Tests/FrameworkApplicationFixture.h similarity index 100% rename from Code/Framework/Tests/FrameworkApplicationFixture.h rename to Code/Framework/AzFramework/Tests/FrameworkApplicationFixture.h diff --git a/Code/Framework/Tests/GenAppDescriptors.cpp b/Code/Framework/AzFramework/Tests/GenAppDescriptors.cpp similarity index 100% rename from Code/Framework/Tests/GenAppDescriptors.cpp rename to Code/Framework/AzFramework/Tests/GenAppDescriptors.cpp diff --git a/Code/Framework/Tests/InputTests.cpp b/Code/Framework/AzFramework/Tests/InputTests.cpp similarity index 100% rename from Code/Framework/Tests/InputTests.cpp rename to Code/Framework/AzFramework/Tests/InputTests.cpp diff --git a/Code/Framework/Tests/Mocks/MockSpawnableEntitiesInterface.h b/Code/Framework/AzFramework/Tests/Mocks/MockSpawnableEntitiesInterface.h similarity index 100% rename from Code/Framework/Tests/Mocks/MockSpawnableEntitiesInterface.h rename to Code/Framework/AzFramework/Tests/Mocks/MockSpawnableEntitiesInterface.h diff --git a/Code/Framework/Tests/NativeWindow.cpp b/Code/Framework/AzFramework/Tests/NativeWindow.cpp similarity index 100% rename from Code/Framework/Tests/NativeWindow.cpp rename to Code/Framework/AzFramework/Tests/NativeWindow.cpp diff --git a/Code/Framework/Tests/OctreePerformanceTests.cpp b/Code/Framework/AzFramework/Tests/OctreePerformanceTests.cpp similarity index 100% rename from Code/Framework/Tests/OctreePerformanceTests.cpp rename to Code/Framework/AzFramework/Tests/OctreePerformanceTests.cpp diff --git a/Code/Framework/Tests/OctreeTests.cpp b/Code/Framework/AzFramework/Tests/OctreeTests.cpp similarity index 100% rename from Code/Framework/Tests/OctreeTests.cpp rename to Code/Framework/AzFramework/Tests/OctreeTests.cpp diff --git a/Code/Framework/Tests/Platform/Android/AzFrameworkTests_Traits_Android.h b/Code/Framework/AzFramework/Tests/Platform/Android/AzFrameworkTests_Traits_Android.h similarity index 100% rename from Code/Framework/Tests/Platform/Android/AzFrameworkTests_Traits_Android.h rename to Code/Framework/AzFramework/Tests/Platform/Android/AzFrameworkTests_Traits_Android.h diff --git a/Code/Framework/Tests/Platform/Android/AzFrameworkTests_Traits_Platform.h b/Code/Framework/AzFramework/Tests/Platform/Android/AzFrameworkTests_Traits_Platform.h similarity index 100% rename from Code/Framework/Tests/Platform/Android/AzFrameworkTests_Traits_Platform.h rename to Code/Framework/AzFramework/Tests/Platform/Android/AzFrameworkTests_Traits_Platform.h diff --git a/Code/Framework/Tests/Platform/Android/platform_android_files.cmake b/Code/Framework/AzFramework/Tests/Platform/Android/platform_android_files.cmake similarity index 100% rename from Code/Framework/Tests/Platform/Android/platform_android_files.cmake rename to Code/Framework/AzFramework/Tests/Platform/Android/platform_android_files.cmake diff --git a/Code/Framework/Tests/Platform/Linux/AzFrameworkTests_Traits_Linux.h b/Code/Framework/AzFramework/Tests/Platform/Linux/AzFrameworkTests_Traits_Linux.h similarity index 100% rename from Code/Framework/Tests/Platform/Linux/AzFrameworkTests_Traits_Linux.h rename to Code/Framework/AzFramework/Tests/Platform/Linux/AzFrameworkTests_Traits_Linux.h diff --git a/Code/Framework/Tests/Platform/Linux/AzFrameworkTests_Traits_Platform.h b/Code/Framework/AzFramework/Tests/Platform/Linux/AzFrameworkTests_Traits_Platform.h similarity index 100% rename from Code/Framework/Tests/Platform/Linux/AzFrameworkTests_Traits_Platform.h rename to Code/Framework/AzFramework/Tests/Platform/Linux/AzFrameworkTests_Traits_Platform.h diff --git a/Code/Framework/Tests/Platform/Linux/platform_linux_files.cmake b/Code/Framework/AzFramework/Tests/Platform/Linux/platform_linux_files.cmake similarity index 100% rename from Code/Framework/Tests/Platform/Linux/platform_linux_files.cmake rename to Code/Framework/AzFramework/Tests/Platform/Linux/platform_linux_files.cmake diff --git a/Code/Framework/Tests/Platform/Mac/AzFrameworkTests_Traits_Mac.h b/Code/Framework/AzFramework/Tests/Platform/Mac/AzFrameworkTests_Traits_Mac.h similarity index 100% rename from Code/Framework/Tests/Platform/Mac/AzFrameworkTests_Traits_Mac.h rename to Code/Framework/AzFramework/Tests/Platform/Mac/AzFrameworkTests_Traits_Mac.h diff --git a/Code/Framework/Tests/Platform/Mac/AzFrameworkTests_Traits_Platform.h b/Code/Framework/AzFramework/Tests/Platform/Mac/AzFrameworkTests_Traits_Platform.h similarity index 100% rename from Code/Framework/Tests/Platform/Mac/AzFrameworkTests_Traits_Platform.h rename to Code/Framework/AzFramework/Tests/Platform/Mac/AzFrameworkTests_Traits_Platform.h diff --git a/Code/Framework/Tests/Platform/Mac/platform_mac_files.cmake b/Code/Framework/AzFramework/Tests/Platform/Mac/platform_mac_files.cmake similarity index 100% rename from Code/Framework/Tests/Platform/Mac/platform_mac_files.cmake rename to Code/Framework/AzFramework/Tests/Platform/Mac/platform_mac_files.cmake diff --git a/Code/Framework/Tests/Platform/Windows/AzFrameworkTests_Traits_Platform.h b/Code/Framework/AzFramework/Tests/Platform/Windows/AzFrameworkTests_Traits_Platform.h similarity index 100% rename from Code/Framework/Tests/Platform/Windows/AzFrameworkTests_Traits_Platform.h rename to Code/Framework/AzFramework/Tests/Platform/Windows/AzFrameworkTests_Traits_Platform.h diff --git a/Code/Framework/Tests/Platform/Windows/AzFrameworkTests_Traits_Windows.h b/Code/Framework/AzFramework/Tests/Platform/Windows/AzFrameworkTests_Traits_Windows.h similarity index 100% rename from Code/Framework/Tests/Platform/Windows/AzFrameworkTests_Traits_Windows.h rename to Code/Framework/AzFramework/Tests/Platform/Windows/AzFrameworkTests_Traits_Windows.h diff --git a/Code/Framework/Tests/Platform/Windows/platform_windows_files.cmake b/Code/Framework/AzFramework/Tests/Platform/Windows/platform_windows_files.cmake similarity index 100% rename from Code/Framework/Tests/Platform/Windows/platform_windows_files.cmake rename to Code/Framework/AzFramework/Tests/Platform/Windows/platform_windows_files.cmake diff --git a/Code/Framework/Tests/Platform/iOS/AzFrameworkTests_Traits_Platform.h b/Code/Framework/AzFramework/Tests/Platform/iOS/AzFrameworkTests_Traits_Platform.h similarity index 100% rename from Code/Framework/Tests/Platform/iOS/AzFrameworkTests_Traits_Platform.h rename to Code/Framework/AzFramework/Tests/Platform/iOS/AzFrameworkTests_Traits_Platform.h diff --git a/Code/Framework/Tests/Platform/iOS/AzFrameworkTests_Traits_iOS.h b/Code/Framework/AzFramework/Tests/Platform/iOS/AzFrameworkTests_Traits_iOS.h similarity index 100% rename from Code/Framework/Tests/Platform/iOS/AzFrameworkTests_Traits_iOS.h rename to Code/Framework/AzFramework/Tests/Platform/iOS/AzFrameworkTests_Traits_iOS.h diff --git a/Code/Framework/Tests/Platform/iOS/platform_ios_files.cmake b/Code/Framework/AzFramework/Tests/Platform/iOS/platform_ios_files.cmake similarity index 100% rename from Code/Framework/Tests/Platform/iOS/platform_ios_files.cmake rename to Code/Framework/AzFramework/Tests/Platform/iOS/platform_ios_files.cmake diff --git a/Code/Framework/Tests/PlatformHelper.cpp b/Code/Framework/AzFramework/Tests/PlatformHelper.cpp similarity index 100% rename from Code/Framework/Tests/PlatformHelper.cpp rename to Code/Framework/AzFramework/Tests/PlatformHelper.cpp diff --git a/Code/Framework/Tests/ProcessLaunchMain.cpp b/Code/Framework/AzFramework/Tests/ProcessLaunchMain.cpp similarity index 100% rename from Code/Framework/Tests/ProcessLaunchMain.cpp rename to Code/Framework/AzFramework/Tests/ProcessLaunchMain.cpp diff --git a/Code/Framework/Tests/ProcessLaunchParseTests.cpp b/Code/Framework/AzFramework/Tests/ProcessLaunchParseTests.cpp similarity index 100% rename from Code/Framework/Tests/ProcessLaunchParseTests.cpp rename to Code/Framework/AzFramework/Tests/ProcessLaunchParseTests.cpp diff --git a/Code/Framework/Tests/Scene.cpp b/Code/Framework/AzFramework/Tests/Scene.cpp similarity index 100% rename from Code/Framework/Tests/Scene.cpp rename to Code/Framework/AzFramework/Tests/Scene.cpp diff --git a/Code/Framework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp b/Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp similarity index 100% rename from Code/Framework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp rename to Code/Framework/AzFramework/Tests/Spawnable/SpawnableEntitiesManagerTests.cpp diff --git a/Code/Framework/Tests/Utils/Utils.cpp b/Code/Framework/AzFramework/Tests/Utils/Utils.cpp similarity index 100% rename from Code/Framework/Tests/Utils/Utils.cpp rename to Code/Framework/AzFramework/Tests/Utils/Utils.cpp diff --git a/Code/Framework/Tests/Utils/Utils.h b/Code/Framework/AzFramework/Tests/Utils/Utils.h similarity index 100% rename from Code/Framework/Tests/Utils/Utils.h rename to Code/Framework/AzFramework/Tests/Utils/Utils.h diff --git a/Code/Framework/Tests/framework_shared_tests_files.cmake b/Code/Framework/AzFramework/Tests/framework_shared_tests_files.cmake similarity index 100% rename from Code/Framework/Tests/framework_shared_tests_files.cmake rename to Code/Framework/AzFramework/Tests/framework_shared_tests_files.cmake diff --git a/Code/Framework/Tests/frameworktests_files.cmake b/Code/Framework/AzFramework/Tests/frameworktests_files.cmake similarity index 100% rename from Code/Framework/Tests/frameworktests_files.cmake rename to Code/Framework/AzFramework/Tests/frameworktests_files.cmake diff --git a/Code/Framework/Tests/process_launch_test_files.cmake b/Code/Framework/AzFramework/Tests/process_launch_test_files.cmake similarity index 100% rename from Code/Framework/Tests/process_launch_test_files.cmake rename to Code/Framework/AzFramework/Tests/process_launch_test_files.cmake diff --git a/Code/Framework/Tests/ComponentAdapterTests.cpp b/Code/Framework/AzToolsFramework/Tests/ComponentAdapterTests.cpp similarity index 100% rename from Code/Framework/Tests/ComponentAdapterTests.cpp rename to Code/Framework/AzToolsFramework/Tests/ComponentAdapterTests.cpp diff --git a/Code/Framework/Tests/ComponentAddRemove.cpp b/Code/Framework/AzToolsFramework/Tests/ComponentAddRemove.cpp similarity index 100% rename from Code/Framework/Tests/ComponentAddRemove.cpp rename to Code/Framework/AzToolsFramework/Tests/ComponentAddRemove.cpp diff --git a/Code/Framework/Tests/EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp b/Code/Framework/AzToolsFramework/Tests/EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp similarity index 100% rename from Code/Framework/Tests/EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp rename to Code/Framework/AzToolsFramework/Tests/EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp diff --git a/Code/Framework/Tests/EntityOwnershipService/EntityOwnershipServiceTestFixture.h b/Code/Framework/AzToolsFramework/Tests/EntityOwnershipService/EntityOwnershipServiceTestFixture.h similarity index 100% rename from Code/Framework/Tests/EntityOwnershipService/EntityOwnershipServiceTestFixture.h rename to Code/Framework/AzToolsFramework/Tests/EntityOwnershipService/EntityOwnershipServiceTestFixture.h diff --git a/Code/Framework/Tests/EntityOwnershipService/SliceEditorEntityOwnershipTests.cpp b/Code/Framework/AzToolsFramework/Tests/EntityOwnershipService/SliceEditorEntityOwnershipTests.cpp similarity index 100% rename from Code/Framework/Tests/EntityOwnershipService/SliceEditorEntityOwnershipTests.cpp rename to Code/Framework/AzToolsFramework/Tests/EntityOwnershipService/SliceEditorEntityOwnershipTests.cpp diff --git a/Code/Framework/Tests/EntityOwnershipService/SliceEntityOwnershipTests.cpp b/Code/Framework/AzToolsFramework/Tests/EntityOwnershipService/SliceEntityOwnershipTests.cpp similarity index 100% rename from Code/Framework/Tests/EntityOwnershipService/SliceEntityOwnershipTests.cpp rename to Code/Framework/AzToolsFramework/Tests/EntityOwnershipService/SliceEntityOwnershipTests.cpp diff --git a/Code/Framework/Tests/EntityTestbed.h b/Code/Framework/AzToolsFramework/Tests/EntityTestbed.h similarity index 100% rename from Code/Framework/Tests/EntityTestbed.h rename to Code/Framework/AzToolsFramework/Tests/EntityTestbed.h diff --git a/Code/Framework/Tests/FileFunc.cpp b/Code/Framework/AzToolsFramework/Tests/FileFunc.cpp similarity index 100% rename from Code/Framework/Tests/FileFunc.cpp rename to Code/Framework/AzToolsFramework/Tests/FileFunc.cpp diff --git a/Code/Framework/Tests/GenericComponentWrapperTest.cpp b/Code/Framework/AzToolsFramework/Tests/GenericComponentWrapperTest.cpp similarity index 100% rename from Code/Framework/Tests/GenericComponentWrapperTest.cpp rename to Code/Framework/AzToolsFramework/Tests/GenericComponentWrapperTest.cpp diff --git a/Code/Framework/Tests/InstanceDataHierarchy.cpp b/Code/Framework/AzToolsFramework/Tests/InstanceDataHierarchy.cpp similarity index 100% rename from Code/Framework/Tests/InstanceDataHierarchy.cpp rename to Code/Framework/AzToolsFramework/Tests/InstanceDataHierarchy.cpp diff --git a/Code/Framework/Tests/SQLiteConnectionTests.cpp b/Code/Framework/AzToolsFramework/Tests/SQLiteConnectionTests.cpp similarity index 100% rename from Code/Framework/Tests/SQLiteConnectionTests.cpp rename to Code/Framework/AzToolsFramework/Tests/SQLiteConnectionTests.cpp diff --git a/Code/Framework/Tests/Script/ScriptComponentTests.cpp b/Code/Framework/AzToolsFramework/Tests/Script/ScriptComponentTests.cpp similarity index 100% rename from Code/Framework/Tests/Script/ScriptComponentTests.cpp rename to Code/Framework/AzToolsFramework/Tests/Script/ScriptComponentTests.cpp diff --git a/Code/Framework/Tests/Script/ScriptEntityTests.cpp b/Code/Framework/AzToolsFramework/Tests/Script/ScriptEntityTests.cpp similarity index 100% rename from Code/Framework/Tests/Script/ScriptEntityTests.cpp rename to Code/Framework/AzToolsFramework/Tests/Script/ScriptEntityTests.cpp diff --git a/Code/Framework/Tests/Slices.cpp b/Code/Framework/AzToolsFramework/Tests/Slices.cpp similarity index 100% rename from Code/Framework/Tests/Slices.cpp rename to Code/Framework/AzToolsFramework/Tests/Slices.cpp diff --git a/Code/Framework/Tests/TransformComponent.cpp b/Code/Framework/AzToolsFramework/Tests/TransformComponent.cpp similarity index 100% rename from Code/Framework/Tests/TransformComponent.cpp rename to Code/Framework/AzToolsFramework/Tests/TransformComponent.cpp From c13720e255163d4ea994ab41003be17eaddfec1b Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Fri, 9 Jul 2021 08:09:00 -0700 Subject: [PATCH 20/53] fixes and cmake changes to get it to compile Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- Code/Framework/AzFramework/CMakeLists.txt | 60 +++++++++++++++++ .../AzFramework/Tests/CMakeLists.txt | 64 ------------------- .../AzFramework/Tests/GenAppDescriptors.cpp | 8 +-- Code/Framework/AzFramework/Tests/Scene.cpp | 1 - .../Tests/framework_shared_tests_files.cmake | 1 + .../Tests/frameworktests_files.cmake | 18 +----- .../Framework/AzToolsFramework/CMakeLists.txt | 1 + .../AzToolsFramework/Tests/FileFunc.cpp | 4 +- .../AzToolsFramework/Tests/Slices.cpp | 38 +++++------ .../Tests/aztoolsframeworktests_files.cmake | 15 +++++ Code/Framework/CMakeLists.txt | 1 - 11 files changed, 103 insertions(+), 108 deletions(-) delete mode 100644 Code/Framework/AzFramework/Tests/CMakeLists.txt diff --git a/Code/Framework/AzFramework/CMakeLists.txt b/Code/Framework/AzFramework/CMakeLists.txt index 1f53472ff8..2cfc5e4b89 100644 --- a/Code/Framework/AzFramework/CMakeLists.txt +++ b/Code/Framework/AzFramework/CMakeLists.txt @@ -52,3 +52,63 @@ ly_add_source_properties( PROPERTY COMPILE_DEFINITIONS VALUES TOUCHBENDING_LAYER_BIT=${LY_TOUCHBENDING_LAYER_BIT} ) + +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) + + ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Tests/Platform/${PAL_PLATFORM_NAME}) + + ly_add_target( + NAME AzFrameworkTestShared STATIC + NAMESPACE AZ + FILES_CMAKE + Tests/framework_shared_tests_files.cmake + INCLUDE_DIRECTORIES + PUBLIC + Tests + BUILD_DEPENDENCIES + PRIVATE + AZ::AzCore + AZ::AzFramework + ) + + if(PAL_TRAIT_BUILD_HOST_TOOLS) + + ly_add_target( + NAME ProcessLaunchTest EXECUTABLE + NAMESPACE AZ + FILES_CMAKE + Tests/process_launch_test_files.cmake + INCLUDE_DIRECTORIES + PRIVATE + Tests + BUILD_DEPENDENCIES + PRIVATE + AZ::AzCore + AZ::AzFramework + ) + + ly_add_target( + NAME AzFramework.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} + NAMESPACE AZ + FILES_CMAKE + Tests/frameworktests_files.cmake + INCLUDE_DIRECTORIES + PRIVATE + Tests + ${pal_dir} + BUILD_DEPENDENCIES + PRIVATE + AZ::AzFramework + AZ::AzTest + AZ::AzTestShared + AZ::AzFrameworkTestShared + RUNTIME_DEPENDENCIES + AZ::ProcessLaunchTest + ) + ly_add_googletest( + NAME AZ::AzFramework.Tests + ) + + endif() + +endif() \ No newline at end of file diff --git a/Code/Framework/AzFramework/Tests/CMakeLists.txt b/Code/Framework/AzFramework/Tests/CMakeLists.txt deleted file mode 100644 index 6781466413..0000000000 --- a/Code/Framework/AzFramework/Tests/CMakeLists.txt +++ /dev/null @@ -1,64 +0,0 @@ -# -# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. -# -# SPDX-License-Identifier: Apache-2.0 OR MIT -# -# - -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) - - ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) - - ly_add_target( - NAME AzFrameworkTestShared STATIC - NAMESPACE AZ - FILES_CMAKE - framework_shared_tests_files.cmake - INCLUDE_DIRECTORIES - PUBLIC - . - BUILD_DEPENDENCIES - PRIVATE - AZ::AzCore - AZ::AzFramework - ) - - if(PAL_TRAIT_BUILD_HOST_TOOLS) - ly_add_target( - NAME ProcessLaunchTest EXECUTABLE - NAMESPACE AZ - FILES_CMAKE - process_launch_test_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - . - BUILD_DEPENDENCIES - PRIVATE - AZ::AzCore - AZ::AzFramework - ) - - ly_add_target( - NAME Framework.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} - NAMESPACE AZ - FILES_CMAKE - frameworktests_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - . - ${pal_dir} - BUILD_DEPENDENCIES - PRIVATE - AZ::AzTest - AZ::AzToolsFramework - AZ::AzTestShared - AZ::AzFrameworkTestShared - RUNTIME_DEPENDENCIES - AZ::ProcessLaunchTest - ) - ly_add_googletest( - NAME AZ::Framework.Tests - ) - endif() - -endif() diff --git a/Code/Framework/AzFramework/Tests/GenAppDescriptors.cpp b/Code/Framework/AzFramework/Tests/GenAppDescriptors.cpp index dde3800895..069d3b35f2 100644 --- a/Code/Framework/AzFramework/Tests/GenAppDescriptors.cpp +++ b/Code/Framework/AzFramework/Tests/GenAppDescriptors.cpp @@ -15,16 +15,16 @@ namespace UnitTest { using namespace AZ; - class SetRestoreFileIOBaseRAII + class FileIOBaseRAII { public: - SetRestoreFileIOBaseRAII(AZ::IO::FileIOBase& fileIO) + FileIOBaseRAII(AZ::IO::FileIOBase& fileIO) : m_prevFileIO(AZ::IO::FileIOBase::GetInstance()) { AZ::IO::FileIOBase::SetInstance(&fileIO); } - ~SetRestoreFileIOBaseRAII() + ~FileIOBaseRAII() { AZ::IO::FileIOBase::SetInstance(m_prevFileIO); } @@ -102,7 +102,7 @@ namespace UnitTest TEST_F(GenAppDescriptors, Test) { AZ::IO::LocalFileIO fileIO; - SetRestoreFileIOBaseRAII restoreFileIOScope(fileIO); + FileIOBaseRAII restoreFileIOScope(fileIO); run(); } } diff --git a/Code/Framework/AzFramework/Tests/Scene.cpp b/Code/Framework/AzFramework/Tests/Scene.cpp index 32a0958692..57293c9d77 100644 --- a/Code/Framework/AzFramework/Tests/Scene.cpp +++ b/Code/Framework/AzFramework/Tests/Scene.cpp @@ -9,7 +9,6 @@ AZ_PUSH_DISABLE_WARNING(, "-Wdelete-non-virtual-dtor") -#include #include #include #include diff --git a/Code/Framework/AzFramework/Tests/framework_shared_tests_files.cmake b/Code/Framework/AzFramework/Tests/framework_shared_tests_files.cmake index 72ffdf0043..5ee7ff644b 100644 --- a/Code/Framework/AzFramework/Tests/framework_shared_tests_files.cmake +++ b/Code/Framework/AzFramework/Tests/framework_shared_tests_files.cmake @@ -9,4 +9,5 @@ set(FILES Mocks/MockSpawnableEntitiesInterface.h Utils/Utils.h Utils/Utils.cpp + FrameworkApplicationFixture.h ) diff --git a/Code/Framework/AzFramework/Tests/frameworktests_files.cmake b/Code/Framework/AzFramework/Tests/frameworktests_files.cmake index 398bb8f45b..25c56f5a71 100644 --- a/Code/Framework/AzFramework/Tests/frameworktests_files.cmake +++ b/Code/Framework/AzFramework/Tests/frameworktests_files.cmake @@ -6,44 +6,28 @@ # set(FILES - ../AzCore/Tests/Main.cpp + ../../AzCore/Tests/Main.cpp Spawnable/SpawnableEntitiesManagerTests.cpp ArchiveCompressionTests.cpp ArchiveTests.cpp BehaviorEntityTests.cpp BinToTextEncode.cpp - ComponentAddRemove.cpp - ComponentAdapterTests.cpp CameraInputTests.cpp ClickDetectorTests.cpp CursorStateTests.cpp EntityContext.cpp - EntityTestbed.h - FileFunc.cpp FileIO.cpp FileTagTests.cpp - FrameworkApplicationFixture.h GenAppDescriptors.cpp - GenericComponentWrapperTest.cpp - InstanceDataHierarchy.cpp OctreePerformanceTests.cpp OctreeTests.cpp - Slices.cpp - Script/ScriptComponentTests.cpp - Script/ScriptEntityTests.cpp AssetCatalog.cpp AssetProcessorConnection.cpp NativeWindow.cpp - TransformComponent.cpp - SQLiteConnectionTests.cpp ProcessLaunchParseTests.cpp Application.cpp PlatformHelper.cpp Scene.cpp - EntityOwnershipService/EntityOwnershipServiceTestFixture.h - EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp - EntityOwnershipService/SliceEditorEntityOwnershipTests.cpp - EntityOwnershipService/SliceEntityOwnershipTests.cpp CameraState.cpp InputTests.cpp ) diff --git a/Code/Framework/AzToolsFramework/CMakeLists.txt b/Code/Framework/AzToolsFramework/CMakeLists.txt index b2a9690948..9a54ee5226 100644 --- a/Code/Framework/AzToolsFramework/CMakeLists.txt +++ b/Code/Framework/AzToolsFramework/CMakeLists.txt @@ -76,6 +76,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) PRIVATE AZ::AzTestShared 3rdParty::Qt::Test + AZ::AzFrameworkTestShared AZ::AzToolsFramework AZ::AzToolsFrameworkTestCommon AZ::AzManipulatorTestFramework.Static diff --git a/Code/Framework/AzToolsFramework/Tests/FileFunc.cpp b/Code/Framework/AzToolsFramework/Tests/FileFunc.cpp index 4edb91164c..420caa0f55 100644 --- a/Code/Framework/AzToolsFramework/Tests/FileFunc.cpp +++ b/Code/Framework/AzToolsFramework/Tests/FileFunc.cpp @@ -5,8 +5,8 @@ * */ -#include "FrameworkApplicationFixture.h" -#include "Utils/Utils.h" +#include +#include #include #include #include diff --git a/Code/Framework/AzToolsFramework/Tests/Slices.cpp b/Code/Framework/AzToolsFramework/Tests/Slices.cpp index ba413eb727..a8c98d2a85 100644 --- a/Code/Framework/AzToolsFramework/Tests/Slices.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Slices.cpp @@ -972,11 +972,11 @@ namespace UnitTest }; - class TestExportEditorComponent + class SliceTestExportEditorComponent : public AzToolsFramework::Components::EditorComponentBase { public: - AZ_COMPONENT(TestExportEditorComponent, "{8FA877A2-38E6-49AD-B31E-71B86DC8BB03}", AzToolsFramework::Components::EditorComponentBase); + AZ_COMPONENT(SliceTestExportEditorComponent, "{8FA877A2-38E6-49AD-B31E-71B86DC8BB03}", AzToolsFramework::Components::EditorComponentBase); enum ExportComponentType { @@ -986,9 +986,9 @@ namespace UnitTest EXPORT_NULL_COMPONENT }; - TestExportEditorComponent() {} + SliceTestExportEditorComponent() {} - TestExportEditorComponent(ExportComponentType exportType, bool exportHandled) : + SliceTestExportEditorComponent(ExportComponentType exportType, bool exportHandled) : m_exportType(exportType), m_exportHandled(exportHandled) {} @@ -1000,15 +1000,15 @@ namespace UnitTest { if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) { - serializeContext->Class() + serializeContext->Class() ; if (AZ::EditContext* editContext = serializeContext->GetEditContext()) { - editContext->Class( + editContext->Class( "Test Export Editor Component", "Validate different options for exporting editor components") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::RuntimeExportCallback, &TestExportEditorComponent::ExportComponent) + ->Attribute(AZ::Edit::Attributes::RuntimeExportCallback, &SliceTestExportEditorComponent::ExportComponent) ; } } @@ -1070,7 +1070,7 @@ namespace UnitTest m_app.RegisterComponentDescriptor(TestExportRuntimeComponent::CreateDescriptor()); m_app.RegisterComponentDescriptor(TestExportOtherRuntimeComponent::CreateDescriptor()); - m_app.RegisterComponentDescriptor(TestExportEditorComponent::CreateDescriptor()); + m_app.RegisterComponentDescriptor(SliceTestExportEditorComponent::CreateDescriptor()); m_editorSliceAsset = Data::AssetManager::Instance().CreateAsset(Data::AssetId(Uuid::CreateRandom())); @@ -1125,11 +1125,11 @@ namespace UnitTest } // create entity containing the EditorOnly component in the editor slice - void CreateTestExportEditorEntity(const char* name, TestExportEditorComponent::ExportComponentType exportType, bool exportHandled) + void CreateTestExportEditorEntity(const char* name, SliceTestExportEditorComponent::ExportComponentType exportType, bool exportHandled) { AZ::Entity* entity = aznew AZ::Entity(name); entity->CreateComponent(); - entity->CreateComponent(exportType, exportHandled); + entity->CreateComponent(exportType, exportHandled); m_editorSliceComponent->AddEntity(entity); } @@ -1314,7 +1314,7 @@ namespace UnitTest TEST_F(SliceCompilerTest, RuntimeExportCallback_EditorComponentExportedSuccessfully) { // Create an editor component that has a RuntimeExportCallback and successfully exports itself - CreateTestExportEditorEntity("EntityWithEditorComponent", TestExportEditorComponent::ExportComponentType::EXPORT_OTHER_RUNTIME_COMPONENT, true); + CreateTestExportEditorEntity("EntityWithEditorComponent", SliceTestExportEditorComponent::ExportComponentType::EXPORT_OTHER_RUNTIME_COMPONENT, true); if (!CompileSlice()) { @@ -1325,7 +1325,7 @@ namespace UnitTest // (A result of Runtime component means BuildGameEntity() ran instead) AZ::Entity* entity = GetCompiledEntity("EntityWithEditorComponent"); EXPECT_TRUE(entity); - EXPECT_FALSE(entity->FindComponent()); + EXPECT_FALSE(entity->FindComponent()); EXPECT_FALSE(entity->FindComponent()); EXPECT_TRUE(entity->FindComponent()); } @@ -1333,7 +1333,7 @@ namespace UnitTest TEST_F(SliceCompilerTest, RuntimeExportCallback_EditorComponentExportSuppressed) { // Create an editor component that has a RuntimeExportCallback and successfully suppresses itself from exporting - CreateTestExportEditorEntity("EntityWithEditorComponent", TestExportEditorComponent::ExportComponentType::EXPORT_NULL_COMPONENT, true); + CreateTestExportEditorEntity("EntityWithEditorComponent", SliceTestExportEditorComponent::ExportComponentType::EXPORT_NULL_COMPONENT, true); if (!CompileSlice()) { @@ -1343,7 +1343,7 @@ namespace UnitTest // Expected result: exported slice does NOT contain either component. AZ::Entity* entity = GetCompiledEntity("EntityWithEditorComponent"); EXPECT_TRUE(entity); - EXPECT_FALSE(entity->FindComponent()); + EXPECT_FALSE(entity->FindComponent()); EXPECT_FALSE(entity->FindComponent()); EXPECT_FALSE(entity->FindComponent()); } @@ -1351,7 +1351,7 @@ namespace UnitTest TEST_F(SliceCompilerTest, RuntimeExportCallback_EditorComponentExportUnhandledFallbackToBuildGameEntity) { // Create an editor component that has a RuntimeExportCallback, returns a pointer to itself, but says it wasn't handled. - CreateTestExportEditorEntity("EntityWithEditorComponent", TestExportEditorComponent::ExportComponentType::EXPORT_EDITOR_COMPONENT, false); + CreateTestExportEditorEntity("EntityWithEditorComponent", SliceTestExportEditorComponent::ExportComponentType::EXPORT_EDITOR_COMPONENT, false); if (!CompileSlice()) { @@ -1362,7 +1362,7 @@ namespace UnitTest // produced a runtime component. AZ::Entity* entity = GetCompiledEntity("EntityWithEditorComponent"); EXPECT_TRUE(entity); - EXPECT_FALSE(entity->FindComponent()); + EXPECT_FALSE(entity->FindComponent()); EXPECT_TRUE(entity->FindComponent()); EXPECT_FALSE(entity->FindComponent()); } @@ -1370,7 +1370,7 @@ namespace UnitTest TEST_F(SliceCompilerTest, RuntimeExportCallback_EditorComponentExportSuppressedAndUnhandledFallbackToBuildGameEntity) { // Create an editor component that has a RuntimeExportCallback and suppresses itself from exporting, but says it wasn't handled - CreateTestExportEditorEntity("EntityWithEditorComponent", TestExportEditorComponent::ExportComponentType::EXPORT_NULL_COMPONENT, false); + CreateTestExportEditorEntity("EntityWithEditorComponent", SliceTestExportEditorComponent::ExportComponentType::EXPORT_NULL_COMPONENT, false); if (!CompileSlice()) { @@ -1381,7 +1381,7 @@ namespace UnitTest // produced a runtime component. AZ::Entity* entity = GetCompiledEntity("EntityWithEditorComponent"); EXPECT_TRUE(entity); - EXPECT_FALSE(entity->FindComponent()); + EXPECT_FALSE(entity->FindComponent()); EXPECT_TRUE(entity->FindComponent()); EXPECT_FALSE(entity->FindComponent()); } @@ -1389,7 +1389,7 @@ namespace UnitTest TEST_F(SliceCompilerTest, RuntimeExportCallback_EditorComponentFailsToExportItself) { // Create an editor component that has a RuntimeExportCallback and suppresses itself from exporting, but says it wasn't handled - CreateTestExportEditorEntity("EntityWithEditorComponent", TestExportEditorComponent::ExportComponentType::EXPORT_EDITOR_COMPONENT, true); + CreateTestExportEditorEntity("EntityWithEditorComponent", SliceTestExportEditorComponent::ExportComponentType::EXPORT_EDITOR_COMPONENT, true); // We expect the slice compilation to fail, since an editor component is being exported as a game component CompileSlice(false); diff --git a/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake b/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake index 2e2be6f921..573de25d42 100644 --- a/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake +++ b/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake @@ -100,4 +100,19 @@ set(FILES Viewport/ClusterTests.cpp Viewport/ViewportUiWidgetManagerTests.cpp Visibility/EditorVisibilityTests.cpp + ComponentAdapterTests.cpp + ComponentAddRemove.cpp + EntityTestbed.h + GenericComponentWrapperTest.cpp + InstanceDataHierarchy.cpp + Slices.cpp + SQLiteConnectionTests.cpp + TransformComponent.cpp + EntityOwnershipService/EntityOwnershipServiceTestFixture.h + EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp + EntityOwnershipService/SliceEditorEntityOwnershipTests.cpp + EntityOwnershipService/SliceEntityOwnershipTests.cpp + Script/ScriptComponentTests.cpp + Script/ScriptEntityTests.cpp + FileFunc.cpp ) diff --git a/Code/Framework/CMakeLists.txt b/Code/Framework/CMakeLists.txt index e12a8f4cab..880751632c 100644 --- a/Code/Framework/CMakeLists.txt +++ b/Code/Framework/CMakeLists.txt @@ -18,4 +18,3 @@ add_subdirectory(AzNetworking) add_subdirectory(Crcfix) add_subdirectory(GFxFramework) add_subdirectory(GridMate) -add_subdirectory(Tests) From 1dec9d4a9a07f631f96f23f9ee37f2e3ab279799 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Mon, 12 Jul 2021 18:03:10 -0700 Subject: [PATCH 21/53] Fix tests in AzToolsFramework now that the Trace bus is hooked Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- .../Tests/AssetFileInfoListComparison.cpp | 2 ++ .../Tests/AssetSeedManager.cpp | 6 ++++ .../Tests/ComponentModeTests.cpp | 3 ++ .../Tests/EntityInspectorTests.cpp | 1 - .../Framework/AzToolsFramework/Tests/Main.cpp | 2 +- .../Tests/PerforceComponentTests.cpp | 6 +--- .../PlatformAddressedAssetCatalogTests.cpp | 2 ++ .../Tests/Prefab/PrefabInstantiateTests.cpp | 2 ++ .../Tests/Prefab/PrefabLoadTemplateTests.cpp | 22 +++++++++++++-- .../Tests/Prefab/PrefabTestDomUtils.cpp | 28 +++++++++++++++---- .../Tests/Prefab/PrefabTestFixture.h | 3 +- .../Tests/PropertyTreeEditorTests.cpp | 8 ++++++ .../Tests/SliceUpgradeTests.cpp | 5 ++++ .../Tests/ThumbnailerTests.cpp | 5 ---- .../EditorLayerComponentTests.cpp | 2 -- .../Tests/TransformComponent.cpp | 4 +-- .../Tests/UI/EntityPropertyEditorTests.cpp | 7 ----- .../Viewport/ViewportUiWidgetManagerTests.cpp | 15 ++-------- 18 files changed, 77 insertions(+), 46 deletions(-) diff --git a/Code/Framework/AzToolsFramework/Tests/AssetFileInfoListComparison.cpp b/Code/Framework/AzToolsFramework/Tests/AssetFileInfoListComparison.cpp index f950f43abc..2e4641d818 100644 --- a/Code/Framework/AzToolsFramework/Tests/AssetFileInfoListComparison.cpp +++ b/Code/Framework/AzToolsFramework/Tests/AssetFileInfoListComparison.cpp @@ -54,6 +54,7 @@ namespace UnitTest m_localFileIO = aznew AZ::IO::LocalFileIO(); m_priorFileIO = AZ::IO::FileIOBase::GetInstance(); + AZ::IO::FileIOBase::SetInstance(nullptr); AZ::IO::FileIOBase::SetInstance(m_localFileIO); AZ::IO::FileIOBase::GetInstance()->SetAlias("@assets@", GetTestFolderPath().c_str()); @@ -175,6 +176,7 @@ namespace UnitTest delete m_pcCatalog; delete m_localFileIO; m_localFileIO = nullptr; + AZ::IO::FileIOBase::SetInstance(nullptr); AZ::IO::FileIOBase::SetInstance(m_priorFileIO); m_application->Stop(); delete m_application; diff --git a/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp b/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp index 71e4184eb6..52b8cc6a52 100644 --- a/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp +++ b/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp @@ -266,7 +266,9 @@ namespace UnitTest AZ::IO::SystemFile::SetWritable(filePath.c_str(), false); // Attempt to save to the same file. Should not be allowed. + AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_FALSE(m_assetSeedManager->Save(filePath)); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // Clean up the test environment AZ::IO::SystemFile::SetWritable(filePath.c_str(), true); @@ -290,7 +292,9 @@ namespace UnitTest AZ::IO::SystemFile::SetWritable(filePath.c_str(), false); // Attempt to save to the same file. Should not be allowed. + AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_FALSE(m_assetSeedManager->SaveAssetFileInfo(filePath, AzFramework::PlatformFlags::Platform_PC, {})); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // Clean up the test environment AZ::IO::SystemFile::SetWritable(filePath.c_str(), true); @@ -357,7 +361,9 @@ namespace UnitTest m_assetSeedManager->AddSeedAsset(assets[2], AzFramework::PlatformFlags::Platform_PC); // Step we are testing + AZ_TEST_START_TRACE_SUPPRESSION; m_assetSeedManager->AddPlatformToAllSeeds(AzFramework::PlatformId::ANDROID_ID); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // Verification AzFramework::PlatformFlags expectedPlatformFlags = AzFramework::PlatformFlags::Platform_PC | AzFramework::PlatformFlags::Platform_ANDROID; diff --git a/Code/Framework/AzToolsFramework/Tests/ComponentModeTests.cpp b/Code/Framework/AzToolsFramework/Tests/ComponentModeTests.cpp index 775c771a8a..9ee75408e6 100644 --- a/Code/Framework/AzToolsFramework/Tests/ComponentModeTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/ComponentModeTests.cpp @@ -493,7 +493,10 @@ namespace UnitTest // Add placeholder component which implements component mode. entity->CreateComponent(); + AZ_TEST_START_TRACE_SUPPRESSION; entity->Activate(); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Code/Framework/AzToolsFramework/Tests/EntityInspectorTests.cpp b/Code/Framework/AzToolsFramework/Tests/EntityInspectorTests.cpp index 3bc4c092dc..c15034ee33 100644 --- a/Code/Framework/AzToolsFramework/Tests/EntityInspectorTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/EntityInspectorTests.cpp @@ -348,7 +348,6 @@ namespace UnitTest EXPECT_FALSE(AzToolsFramework::ComponentPaletteUtil::ContainsEditableComponents(context, &Filter_IsTestComponent2, AZ::ComponentDescriptor::DependencyArrayType())); // Reflect Test Component 2 for subsequent tests - Inspector_TestComponent2::Reflect(context); m_application->RegisterComponentDescriptor(Inspector_TestComponent2Descriptor); // Verify that there is now a component that satisfies the AppearsInGameComponentMenu filter without service dependency conditions diff --git a/Code/Framework/AzToolsFramework/Tests/Main.cpp b/Code/Framework/AzToolsFramework/Tests/Main.cpp index ff94f9af5c..21aac978b3 100644 --- a/Code/Framework/AzToolsFramework/Tests/Main.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Main.cpp @@ -46,7 +46,7 @@ AZTEST_EXPORT int AZ_UNIT_TEST_HOOK_NAME(int argc, char** argv) } styleManager->initialize(&app, engineRootPath); AZ::Test::printUnusedParametersWarning(argc, argv); - AZ::Test::addTestEnvironments({ new ToolsFrameworkHook }); + AZ::Test::addTestEnvironments({ DEFAULT_UNIT_TEST_ENV, new ToolsFrameworkHook }); int result = RUN_ALL_TESTS(); styleManager.release(); return result; diff --git a/Code/Framework/AzToolsFramework/Tests/PerforceComponentTests.cpp b/Code/Framework/AzToolsFramework/Tests/PerforceComponentTests.cpp index db7430085b..46f9a9fa3a 100644 --- a/Code/Framework/AzToolsFramework/Tests/PerforceComponentTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/PerforceComponentTests.cpp @@ -23,8 +23,7 @@ namespace UnitTest }; struct PerforceComponentFixture - : ::testing::Test - , TraceBusRedirector + : ScopedAllocatorSetupFixture , SourceControlTest { @@ -40,7 +39,6 @@ namespace UnitTest m_jobContext = aznew AZ::JobContext(*m_jobManager); AZ::JobContext::SetGlobalContext(m_jobContext); - AZ::Debug::TraceMessageBus::Handler::BusConnect(); AZ::TickBus::AllowFunctionQueuing(true); m_perforceComponent = AZStd::make_unique(); @@ -52,8 +50,6 @@ namespace UnitTest void TearDown() override { - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - AZ::TickBus::AllowFunctionQueuing(false); AZ::TickBus::ClearQueuedEvents(); diff --git a/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp b/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp index e581f4fac7..2ac66564df 100644 --- a/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp @@ -246,7 +246,9 @@ namespace UnitTest AzFramework::AssetSystem::NetworkAssetUpdateInterface* notificationInterface = AZ::Interface::Get(); EXPECT_NE(notificationInterface, nullptr); + AZ_TEST_START_TRACE_SUPPRESSION; auto* mockCatalog = new ::testing::NiceMock(AzFramework::PlatformId::ANDROID_ID); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; AZStd::unique_ptr< ::testing::NiceMock> catalogHolder; catalogHolder.reset(mockCatalog); diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstantiateTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstantiateTests.cpp index a08de99d3e..81d44d7426 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstantiateTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstantiateTests.cpp @@ -13,7 +13,9 @@ namespace UnitTest TEST_F(PrefabInstantiateTest, PrefabInstantiate_InstantiateInvalidTemplate_InstantiateFails) { + AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_FALSE(m_prefabSystemComponent->InstantiatePrefab(AzToolsFramework::Prefab::InvalidTemplateId)); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; } TEST_F(PrefabInstantiateTest, PrefabInstantiate_NoNestingTemplate_InstantiateSucceeds) diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabLoadTemplateTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabLoadTemplateTests.cpp index 9cf1194834..db7640916d 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabLoadTemplateTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabLoadTemplateTests.cpp @@ -68,8 +68,10 @@ namespace UnitTest MockPrefabFileIOActionValidator mockIOActionValidator; mockIOActionValidator.ReadPrefabDom(templateData.m_filePath, templatePrefabDom); - + + AZ_TEST_START_TRACE_SUPPRESSION; templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(templateData.m_filePath); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; templateData.m_isLoadedWithErrors = true; PrefabTestDataUtils::ValidateTemplateLoad(templateData); @@ -115,7 +117,9 @@ namespace UnitTest targetTemplateData.m_filePath, targetTemplatePrefabDom); // Load target and source Templates and get their Ids. + AZ_TEST_START_TRACE_SUPPRESSION; targetTemplateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(targetTemplateData.m_filePath); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; sourceTemplateData.m_id = m_prefabSystemComponent->GetTemplateIdFromFilePath(sourceTemplateData.m_filePath); // Because of cyclical dependency, the two Templates should be loaded with errors. @@ -144,7 +148,9 @@ namespace UnitTest MockPrefabFileIOActionValidator mockIOActionValidator; mockIOActionValidator.ReadPrefabDom(templateData.m_filePath, templatePrefabDom); + AZ_TEST_START_TRACE_SUPPRESSION; templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(templateData.m_filePath); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; PrefabTestDataUtils::ValidateTemplateLoad(templateData); } @@ -161,7 +167,9 @@ namespace UnitTest MockPrefabFileIOActionValidator mockIOActionValidator; mockIOActionValidator.ReadPrefabDom(templateData.m_filePath, templatePrefabDom); + AZ_TEST_START_TRACE_SUPPRESSION; templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(templateData.m_filePath); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; PrefabTestDataUtils::ValidateTemplateLoad(templateData); } @@ -183,7 +191,9 @@ namespace UnitTest templateInstanceData.m_source, PrefabTestDomUtils::CreatePrefabDom(), AZ::IO::ResultCode::Success, AZ::IO::ResultCode::Error); + AZ_TEST_START_TRACE_SUPPRESSION; templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(templateData.m_filePath); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; PrefabTestDataUtils::ValidateTemplateLoad(templateData); } @@ -279,8 +289,10 @@ namespace UnitTest MockPrefabFileIOActionValidator mockIOActionValidator; mockIOActionValidator.ReadPrefabDom(pathToCorruptedPrefab, corruptedPrefabContent); - + + AZ_TEST_START_TRACE_SUPPRESSION; TemplateId templateId = m_prefabLoaderInterface->LoadTemplateFromFile(pathToCorruptedPrefab); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; EXPECT_EQ(templateId, AzToolsFramework::Prefab::InvalidTemplateId); } @@ -289,8 +301,10 @@ namespace UnitTest { PrefabDom emptyPrefabDom = PrefabTestDomUtils::CreatePrefabDom(); AZStd::string emptyPrefabDomStr = PrefabTestDomUtils::DomToString(emptyPrefabDom); + AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_EQ(m_prefabLoaderInterface->LoadTemplateFromString(emptyPrefabDomStr, "|?<>"), AzToolsFramework::Prefab::InvalidTemplateId); EXPECT_EQ(m_prefabLoaderInterface->LoadTemplateFromString(emptyPrefabDomStr, "notAFile/"), AzToolsFramework::Prefab::InvalidTemplateId); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; } TEST_F(PrefabLoadTemplateTest, LoadTemplate_LoadFromString_LoadsEmptyPrefab) @@ -318,9 +332,11 @@ namespace UnitTest ); AZStd::string selfDependentPrefabStr = PrefabTestDomUtils::DomToString(selfDependentPrefab); + AZ_TEST_START_TRACE_SUPPRESSION; templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromString( selfDependentPrefabStr, templateData.m_filePath); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; templateData.m_isLoadedWithErrors = true; @@ -330,7 +346,9 @@ namespace UnitTest TEST_F(PrefabLoadTemplateTest, LoadTemplate_LoadFromString_CorruptedReturnsInvalidTemplateId) { AZStd::string corruptPrefab = "{ Corrupted PrefabDom"; + AZ_TEST_START_TRACE_SUPPRESSION; TemplateId templateId = m_prefabLoaderInterface->LoadTemplateFromString(corruptPrefab); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; EXPECT_EQ(templateId, AzToolsFramework::Prefab::InvalidTemplateId); } } diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestDomUtils.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestDomUtils.cpp index 34cff98a73..413e3ea0b4 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestDomUtils.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestDomUtils.cpp @@ -166,13 +166,29 @@ namespace UnitTest if (expectedNestedInstanceDomInstances.has_value()) { ASSERT_TRUE(actualNestedInstanceDomInstances.has_value()); - for (auto instanceIterator = expectedNestedInstanceDomInstances->get().MemberBegin(); - instanceIterator != expectedNestedInstanceDomInstances->get().MemberEnd(); ++instanceIterator) + if (expectedNestedInstanceDomInstances->get().IsArray()) { - ComparePrefabDoms( - instanceIterator->value, - PrefabDomUtils::FindPrefabDomValue(actualNestedInstanceDomInstances->get(), instanceIterator->name.GetString()), - shouldCompareLinkIds, shouldCompareContainerEntities); + ASSERT_TRUE(actualNestedInstanceDomInstances->get().IsArray()); + const size_t arraySize = expectedNestedInstanceDomInstances->get().GetArray().Size(); + for(size_t i = 0; i < arraySize; ++i) + { + ComparePrefabDoms( + expectedNestedInstanceDomInstances->get().GetArray()[i], + actualNestedInstanceDomInstances->get().GetArray()[i], + shouldCompareLinkIds, shouldCompareContainerEntities); + } + } + if (expectedNestedInstanceDomInstances->get().IsObject()) + { + ASSERT_TRUE(actualNestedInstanceDomInstances->get().IsObject()); + for (auto instanceIterator = expectedNestedInstanceDomInstances->get().MemberBegin(); + instanceIterator != expectedNestedInstanceDomInstances->get().MemberEnd(); ++instanceIterator) + { + ComparePrefabDoms( + instanceIterator->value, + PrefabDomUtils::FindPrefabDomValue(actualNestedInstanceDomInstances->get(), instanceIterator->name.GetString()), + shouldCompareLinkIds, shouldCompareContainerEntities); + } } } } diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestFixture.h b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestFixture.h index 763d3bec1f..b438f9f28d 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestFixture.h +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestFixture.h @@ -37,8 +37,7 @@ namespace UnitTest }; class PrefabTestFixture - : public ToolsApplicationFixture, - public UnitTest::TraceBusRedirector + : public ToolsApplicationFixture { protected: diff --git a/Code/Framework/AzToolsFramework/Tests/PropertyTreeEditorTests.cpp b/Code/Framework/AzToolsFramework/Tests/PropertyTreeEditorTests.cpp index 99cf334dc9..006dd5a656 100644 --- a/Code/Framework/AzToolsFramework/Tests/PropertyTreeEditorTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/PropertyTreeEditorTests.cpp @@ -426,7 +426,9 @@ namespace UnitTest AZStd::any keyString = AZStd::make_any("0"); EXPECT_FALSE(propertyTree.GetContainerItem("My New Int", key).IsSuccess()); + AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_FALSE(propertyTree.GetContainerItem("My New List", keyString).IsSuccess()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); PropertyTreeEditor::PropertyAccessOutcome outcome = propertyTree.GetContainerItem("My New List", key); EXPECT_TRUE(outcome.IsSuccess()); @@ -446,7 +448,9 @@ namespace UnitTest AZStd::any value = AZStd::make_any(testUpdate); EXPECT_FALSE(propertyTree.UpdateContainerItem("My New Int", key, value).IsSuccess()); + AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_FALSE(propertyTree.UpdateContainerItem("My New List", keyString, value).IsSuccess()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); EXPECT_TRUE(propertyTree.UpdateContainerItem("My New List", key, value).IsSuccess()); PropertyTreeEditor::PropertyAccessOutcome outcome = propertyTree.GetContainerItem("My New List", key); @@ -464,7 +468,9 @@ namespace UnitTest AZStd::any keyString = AZStd::make_any("0"); EXPECT_FALSE(propertyTree.RemoveContainerItem("My New Int", key).IsSuccess()); + AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_FALSE(propertyTree.RemoveContainerItem("My New List", keyString).IsSuccess()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); PropertyTreeEditor::PropertyAccessOutcome outcomeAdd1 = propertyTree.RemoveContainerItem("My New List", key); EXPECT_TRUE(outcomeAdd1.IsSuccess()); @@ -755,7 +761,9 @@ namespace UnitTest EXPECT_TRUE(propertyTree.SetProperty("My Int", anEmpty).IsSuccess()); EXPECT_TRUE(propertyTree.SetProperty("My Negative Short", anEmpty).IsSuccess()); EXPECT_TRUE(propertyTree.SetProperty("My New List", anEmpty).IsSuccess()); + AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_TRUE(propertyTree.SetProperty("My Asset Data", anEmpty).IsSuccess()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); EXPECT_TRUE(propertyTree.SetProperty("My Test Simple Asset", anEmpty).IsSuccess()); } diff --git a/Code/Framework/AzToolsFramework/Tests/SliceUpgradeTests.cpp b/Code/Framework/AzToolsFramework/Tests/SliceUpgradeTests.cpp index 98b004feba..f8acf7d224 100644 --- a/Code/Framework/AzToolsFramework/Tests/SliceUpgradeTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/SliceUpgradeTests.cpp @@ -275,6 +275,7 @@ namespace UnitTest TEST_F(SliceUpgradeTest, IntermmediateDataTypeChange) { TestDataA::Reflect(m_serializeContext.get()); + AzToolsFramework::Components::EditorComponentBase::Reflect(m_serializeContext.get()); TestComponentA_V0::Reflect(m_serializeContext.get()); AZ::Entity* entityA = aznew AZ::Entity(); TestComponentA_V0* component = entityA->CreateComponent(); @@ -320,6 +321,7 @@ namespace UnitTest TEST_F(SliceUpgradeTest, TypeChangeInUnorderedMap) { TestDataB_V0::Reflect(m_serializeContext.get()); + AzToolsFramework::Components::EditorComponentBase::Reflect(m_serializeContext.get()); TestComponentB_V0::Reflect(m_serializeContext.get()); AZ::Entity* entityA = aznew AZ::Entity(); TestComponentB_V0* componentB = entityA->CreateComponent(); @@ -395,6 +397,7 @@ namespace UnitTest TEST_F(SliceUpgradeTest, TypeChangeInVector) { TestDataB_V0::Reflect(m_serializeContext.get()); + AzToolsFramework::Components::EditorComponentBase::Reflect(m_serializeContext.get()); TestComponentC_V0::Reflect(m_serializeContext.get()); AZ::Entity* entityA = aznew AZ::Entity(); TestComponentC_V0* componentC = entityA->CreateComponent(); @@ -452,6 +455,7 @@ namespace UnitTest TEST_F(SliceUpgradeTest, UpgradeSkipVersion_TypeChange_FloatToDouble) { // 1. Create an entity with a TestComponentE_V4 with the default value for m_data + AzToolsFramework::Components::EditorComponentBase::Reflect(m_serializeContext.get()); TestComponentE_V4::Reflect(m_serializeContext.get()); AZ::Entity* testEntity = aznew AZ::Entity(); TestComponentE_V4* componentEV4 = testEntity->CreateComponent(); @@ -563,6 +567,7 @@ namespace UnitTest SliceUpgradeTestAsset::Reflect(m_serializeContext.get()); AzFramework::SimpleAssetReference::Register(*m_serializeContext.get()); + AzToolsFramework::Components::EditorComponentBase::Reflect(m_serializeContext.get()); TestComponentD_V1::Reflect(m_serializeContext.get()); AZ::Entity* entity = aznew AZ::Entity(); entity->CreateComponent(); diff --git a/Code/Framework/AzToolsFramework/Tests/ThumbnailerTests.cpp b/Code/Framework/AzToolsFramework/Tests/ThumbnailerTests.cpp index 05ffc6055f..8c8ebc47e9 100644 --- a/Code/Framework/AzToolsFramework/Tests/ThumbnailerTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/ThumbnailerTests.cpp @@ -20,7 +20,6 @@ namespace UnitTest class ThumbnailerTests : public ::testing::Test - , public TraceBusRedirector { protected: void SetUp() override @@ -31,8 +30,6 @@ namespace UnitTest // was running, because the environment wasn't setup for it to save these settings. AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize); - TraceBusRedirector::BusConnect(); - AZStd::string entityName("test"); AZ::EntityId testEntityId; AzToolsFramework::EditorEntityContextRequestBus::BroadcastResult( @@ -61,8 +58,6 @@ namespace UnitTest void TearDown() override { - TraceBusRedirector::BusDisconnect(); - AzToolsFramework::EditorEntityContextRequestBus::Broadcast( &AzToolsFramework::EditorEntityContextRequestBus::Events::DestroyEditorEntity, m_testEntity->GetId()); diff --git a/Code/Framework/AzToolsFramework/Tests/ToolsComponents/EditorLayerComponentTests.cpp b/Code/Framework/AzToolsFramework/Tests/ToolsComponents/EditorLayerComponentTests.cpp index 3007f12192..0c50ca2e00 100644 --- a/Code/Framework/AzToolsFramework/Tests/ToolsComponents/EditorLayerComponentTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/ToolsComponents/EditorLayerComponentTests.cpp @@ -248,8 +248,6 @@ namespace AzToolsFramework m_app.Stop(); AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - - } // A few tests save a layer and want to check the state after saving. diff --git a/Code/Framework/AzToolsFramework/Tests/TransformComponent.cpp b/Code/Framework/AzToolsFramework/Tests/TransformComponent.cpp index 57edbf7f74..21631571f5 100644 --- a/Code/Framework/AzToolsFramework/Tests/TransformComponent.cpp +++ b/Code/Framework/AzToolsFramework/Tests/TransformComponent.cpp @@ -975,7 +975,7 @@ namespace UnitTest // AzToolsFramework::Components::TransformComponent // Fixture base class for AzToolsFramework::Components::TransformComponent tests - class EditorTransformComponentTest + class OldEditorTransformComponentTest : public ::testing::Test { protected: @@ -1000,7 +1000,7 @@ namespace UnitTest // Old TransformComponents used to store "Slice Root" entity Id, which could be its own Id. // The version-converter could end up making an entity into its own transform parent. // The EditorEntityFixupComponent should fix this up during slice instantiation. - TEST_F(EditorTransformComponentTest, OldSliceRoots_ShouldHaveNoParent) + TEST_F(OldEditorTransformComponentTest, OldSliceRoots_ShouldHaveNoParent) { const char kSliceData[] = R"DELIMITER( diff --git a/Code/Framework/AzToolsFramework/Tests/UI/EntityPropertyEditorTests.cpp b/Code/Framework/AzToolsFramework/Tests/UI/EntityPropertyEditorTests.cpp index cf9f95ef31..384edf76ad 100644 --- a/Code/Framework/AzToolsFramework/Tests/UI/EntityPropertyEditorTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/UI/EntityPropertyEditorTests.cpp @@ -127,7 +127,6 @@ namespace UnitTest void SetUpEditorFixtureImpl() override { m_editor = new EntityPropertyEditor(); - m_editorActions.Connect(); m_entity1 = CreateDefaultEditorEntity("Entity1"); m_entity2 = CreateDefaultEditorEntity("Entity2"); @@ -137,13 +136,11 @@ namespace UnitTest void TearDownEditorFixtureImpl() override { - m_editorActions.Disconnect(); delete m_editor; } public: EntityPropertyEditor* m_editor; - TestEditorActions m_editorActions; EntityIdList m_entityIds; AZ::EntityId m_entity1; AZ::EntityId m_entity2; @@ -234,8 +231,6 @@ namespace UnitTest entities.insert(m_levelEntity); m_levelEditor->SetOverrideEntityIds(entities); - m_editorActions.Connect(); - // Connect to the EditorRequestBus so that we can intercept calls checking whether or not a level is currently open. AzToolsFramework::EditorRequestBus::Handler::BusConnect(); } @@ -244,7 +239,6 @@ namespace UnitTest { AzToolsFramework::EditorRequestBus::Handler::BusDisconnect(); - m_editorActions.Disconnect(); delete m_levelEditor; } @@ -258,7 +252,6 @@ namespace UnitTest public: EntityPropertyEditor* m_levelEditor; - TestEditorActions m_editorActions; AZ::EntityId m_levelEntity; bool m_levelOpen = false; }; diff --git a/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportUiWidgetManagerTests.cpp b/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportUiWidgetManagerTests.cpp index f1d282e869..7480c937f4 100644 --- a/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportUiWidgetManagerTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportUiWidgetManagerTests.cpp @@ -85,19 +85,8 @@ namespace UnitTest } class ViewportUiWidgetAssertFixture - : public ::testing::Test - , UnitTest::TraceBusRedirector - { - public: - void SetUp() override - { - AZ::Debug::TraceMessageBus::Handler::BusConnect(); - } - void TearDown() override - { - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - } - }; + : public ScopedAllocatorSetupFixture + {}; TEST_F(ViewportUiWidgetAssertFixture, RegisterUpdateCallbackDoesNotRegisterFunctionForNotAddedObject) { From 900f37644e33e8d960d9effe81824b8a6d504d80 Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Mon, 12 Jul 2021 18:19:41 -0700 Subject: [PATCH 22/53] fix Atom GPU test by enabling autotest_mode (#2117) Signed-off-by: jromnoa --- .../Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py | 1 - 1 file changed, 1 deletion(-) diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py index 01974218b1..05eff871c1 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py @@ -77,7 +77,6 @@ class TestAllComponentsIndepthTests(object): unexpected_lines=unexpected_lines, halt_on_unexpected=True, cfg_args=[level], - auto_test_mode=False, null_renderer=False, ) From 4e84738ff25b60575a97824e0f71105d82cec253 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Mon, 12 Jul 2021 20:32:08 -0700 Subject: [PATCH 23/53] Ordering file alphabetically Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- .../Tests/aztoolsframeworktests_files.cmake | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake b/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake index 573de25d42..9d1ec3e346 100644 --- a/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake +++ b/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake @@ -11,35 +11,37 @@ set(FILES AssetFileInfoListComparison.cpp AssetSeedManager.cpp AssetSystemMocks.h - ComponentModeTests.cpp - ComponentModeTestDoubles.h + ComponentAdapterTests.cpp + ComponentAddRemove.cpp ComponentModeTestDoubles.cpp - ComponentModeTestFixture.h + ComponentModeTestDoubles.h ComponentModeTestFixture.cpp + ComponentModeTestFixture.h + ComponentModeTests.cpp EditorTransformComponentSelectionTests.cpp EditorVertexSelectionTests.cpp + Entity/EditorEntityContextComponentTests.cpp + Entity/EditorEntityHelpersTests.cpp + Entity/EditorEntitySearchComponentTests.cpp + Entity/EditorEntitySelectionTests.cpp EntityIdQLabelTests.cpp EntityInspectorTests.cpp + EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp + EntityOwnershipService/EntityOwnershipServiceTestFixture.h + EntityOwnershipService/SliceEditorEntityOwnershipTests.cpp + EntityOwnershipService/SliceEntityOwnershipTests.cpp + EntityTestbed.h + FileFunc.cpp FingerprintingTests.cpp + GenericComponentWrapperTest.cpp + InstanceDataHierarchy.cpp + IntegerPrimtitiveTestConfig.h LogLines.cpp ManipulatorBoundsTests.cpp ManipulatorCoreTests.cpp ManipulatorViewTests.cpp - PlatformAddressedAssetCatalogTests.cpp - PropertyIntCtrlCommonTests.h - IntegerPrimtitiveTestConfig.h - QtWidgetLimitsTests.cpp - PropertyIntSliderCtrlTests.cpp - PropertyIntSpinCtrlTests.cpp - PropertyTreeEditorTests.cpp - PythonBindingTests.cpp - Slice.cpp - SliceUpgradeTestsData.h - SliceUpgradeTests.cpp - SpinBoxTests.cpp - ThumbnailerTests.cpp - UndoStack.cpp PerforceComponentTests.cpp + PlatformAddressedAssetCatalogTests.cpp Prefab/Benchmark/PrefabBenchmarkFixture.cpp Prefab/Benchmark/PrefabBenchmarkFixture.h Prefab/Benchmark/PrefabCreateBenchmarks.cpp @@ -47,13 +49,13 @@ set(FILES Prefab/Benchmark/PrefabLoadBenchmarks.cpp Prefab/Benchmark/PrefabUpdateInstancesBenchmarks.cpp Prefab/Benchmark/SpawnableCreateBenchmarks.cpp - Prefab/Spawnable/SpawnableMetaDataTests.cpp Prefab/MockPrefabFileIOActionValidator.cpp Prefab/MockPrefabFileIOActionValidator.h Prefab/PrefabDuplicateTests.cpp Prefab/PrefabEntityAliasTests.cpp Prefab/PrefabInstanceToTemplatePropagatorTests.cpp Prefab/PrefabInstantiateTests.cpp + Prefab/PrefabInstantiateTests.cpp Prefab/PrefabLoadTemplateTests.cpp Prefab/PrefabTestComponent.cpp Prefab/PrefabTestComponent.h @@ -67,52 +69,50 @@ set(FILES Prefab/PrefabTestFixture.h Prefab/PrefabTestUndoFixture.cpp Prefab/PrefabTestUndoFixture.h + Prefab/PrefabTestUtils.h Prefab/PrefabUndoLinkTests.cpp Prefab/PrefabUndoTests.cpp - Prefab/PrefabTestUtils.h Prefab/PrefabUpdateInstancesTests.cpp Prefab/PrefabUpdateTemplateTests.cpp Prefab/PrefabUpdateWithPatchesTests.cpp - Prefab/PrefabInstantiateTests.cpp + Prefab/Spawnable/SpawnableMetaDataTests.cpp Prefab/SpawnableCreateTests.cpp - Prefab/SpawnableRemoveEditorInfoTests.cpp Prefab/SpawnableRemoveEditorInfoTestFixture.cpp Prefab/SpawnableRemoveEditorInfoTestFixture.h - Prefab/SpawnableSortEntitiesTests.cpp + Prefab/SpawnableRemoveEditorInfoTests.cpp Prefab/SpawnableSortEntitiesTestFixture.cpp Prefab/SpawnableSortEntitiesTestFixture.h - Entity/EditorEntityContextComponentTests.cpp - Entity/EditorEntityHelpersTests.cpp - Entity/EditorEntitySearchComponentTests.cpp - Entity/EditorEntitySelectionTests.cpp - SliceStabilityTests/SliceStabilityTestFramework.h - SliceStabilityTests/SliceStabilityTestFramework.cpp + Prefab/SpawnableSortEntitiesTests.cpp + PropertyIntCtrlCommonTests.h + PropertyIntSliderCtrlTests.cpp + PropertyIntSpinCtrlTests.cpp + PropertyTreeEditorTests.cpp + PythonBindingTests.cpp + QtWidgetLimitsTests.cpp + Script/ScriptComponentTests.cpp + Script/ScriptEntityTests.cpp + Slice.cpp + Slices.cpp SliceStabilityTests/SliceStabilityCreateTests.cpp SliceStabilityTests/SliceStabilityPushTests.cpp SliceStabilityTests/SliceStabilityReParentTests.cpp + SliceStabilityTests/SliceStabilityTestFramework.cpp + SliceStabilityTests/SliceStabilityTestFramework.h + SliceUpgradeTests.cpp + SliceUpgradeTestsData.h + SpinBoxTests.cpp + SQLiteConnectionTests.cpp + ThumbnailerTests.cpp ToolsComponents/EditorLayerComponentTests.cpp ToolsComponents/EditorTransformComponentTests.cpp + TransformComponent.cpp UI/EntityPropertyEditorTests.cpp + UndoStack.cpp + Viewport/ClusterTests.cpp Viewport/ViewportScreenTests.cpp Viewport/ViewportUiClusterTests.cpp Viewport/ViewportUiDisplayTests.cpp Viewport/ViewportUiManagerTests.cpp - Viewport/ClusterTests.cpp Viewport/ViewportUiWidgetManagerTests.cpp Visibility/EditorVisibilityTests.cpp - ComponentAdapterTests.cpp - ComponentAddRemove.cpp - EntityTestbed.h - GenericComponentWrapperTest.cpp - InstanceDataHierarchy.cpp - Slices.cpp - SQLiteConnectionTests.cpp - TransformComponent.cpp - EntityOwnershipService/EntityOwnershipServiceTestFixture.h - EntityOwnershipService/EntityOwnershipServiceTestFixture.cpp - EntityOwnershipService/SliceEditorEntityOwnershipTests.cpp - EntityOwnershipService/SliceEntityOwnershipTests.cpp - Script/ScriptComponentTests.cpp - Script/ScriptEntityTests.cpp - FileFunc.cpp ) From 42bfefe6c0371688f320a7295ceb823f94e96d90 Mon Sep 17 00:00:00 2001 From: Chris Galvan Date: Tue, 13 Jul 2021 13:02:11 -0500 Subject: [PATCH 24/53] Make new input event groups auto-expanded by default. Signed-off-by: Chris Galvan --- Gems/StartingPointInput/Code/Source/InputEventGroup.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Gems/StartingPointInput/Code/Source/InputEventGroup.h b/Gems/StartingPointInput/Code/Source/InputEventGroup.h index 0ef9797f24..88a27cf3ee 100644 --- a/Gems/StartingPointInput/Code/Source/InputEventGroup.h +++ b/Gems/StartingPointInput/Code/Source/InputEventGroup.h @@ -37,6 +37,7 @@ namespace StartingPointInput editContext->Class("InputEventGroup", "Groups input bindings by the event they generate") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->Attribute(AZ::Edit::Attributes::NameLabelOverride, &InputEventGroup::GetEditorText) + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ->DataElement(0, &InputEventGroup::m_eventName, "Event Name", "The event generated by the collection of Input Bindings") ->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ_CRC("RefreshAttributesAndValues")) ->DataElement(0, &InputEventGroup::m_inputHandlers, "Event Generators", "Handlers that generate named events") From 177f532ffa2595bcb5bed66e4baba09edf41da6a Mon Sep 17 00:00:00 2001 From: Junbo Liang <68558268+junbo75@users.noreply.github.com> Date: Tue, 13 Jul 2021 11:25:57 -0700 Subject: [PATCH 25/53] [Android] SSL certificate error when run the AWS gem sample levels (#2060) [Android] Add AWS CA Cert handling to fix SSL errors. --- .../source/AWSNativeSDKInit.cpp | 4 + .../Android/InitializeCerts_Android.cpp | 89 + .../Android/platform_android_files.cmake | 1 + .../Common/Default/InitializeCerts_Null.cpp | 16 + .../Platform/Linux/platform_linux_files.cmake | 1 + .../Platform/Mac/platform_mac_files.cmake | 1 + .../Windows/platform_windows_files.cmake | 1 + .../Platform/iOS/platform_ios_files.cmake | 1 + .../Source/AWSClientAuthSystemComponent.cpp | 7 +- .../Code/Tests/AWSClientAuthGemMock.h | 21 + .../AWSClientAuthSystemComponentTest.cpp | 2 + .../Assets/Certificates/AWS/cacert.pem | 4043 +++++++++++++++++ Gems/AWSCore/Code/CMakeLists.txt | 2 + .../Code/Source/Framework/AWSApiJob.cpp | 12 + .../Platform/Android/GetCertsPath_Android.cpp | 32 + .../Android/platform_android_files.cmake | 10 + .../Platform/Common/GetCertsPath_Null.cpp | 27 + .../Platform/Linux/platform_linux_files.cmake | 10 + .../Platform/Mac/platform_mac_files.cmake | 10 + .../Windows/platform_windows_files.cmake | 10 + .../Platform/iOS/platform_ios_files.cmake | 10 + 21 files changed, 4309 insertions(+), 1 deletion(-) create mode 100644 Code/Tools/AWSNativeSDKInit/source/Platform/Android/InitializeCerts_Android.cpp create mode 100644 Code/Tools/AWSNativeSDKInit/source/Platform/Common/Default/InitializeCerts_Null.cpp create mode 100644 Gems/AWSCore/Assets/Certificates/AWS/cacert.pem create mode 100644 Gems/AWSCore/Code/Source/Framework/Platform/Android/GetCertsPath_Android.cpp create mode 100644 Gems/AWSCore/Code/Source/Framework/Platform/Android/platform_android_files.cmake create mode 100644 Gems/AWSCore/Code/Source/Framework/Platform/Common/GetCertsPath_Null.cpp create mode 100644 Gems/AWSCore/Code/Source/Framework/Platform/Linux/platform_linux_files.cmake create mode 100644 Gems/AWSCore/Code/Source/Framework/Platform/Mac/platform_mac_files.cmake create mode 100644 Gems/AWSCore/Code/Source/Framework/Platform/Windows/platform_windows_files.cmake create mode 100644 Gems/AWSCore/Code/Source/Framework/Platform/iOS/platform_ios_files.cmake diff --git a/Code/Tools/AWSNativeSDKInit/source/AWSNativeSDKInit.cpp b/Code/Tools/AWSNativeSDKInit/source/AWSNativeSDKInit.cpp index 97802a1516..d92b72e11a 100644 --- a/Code/Tools/AWSNativeSDKInit/source/AWSNativeSDKInit.cpp +++ b/Code/Tools/AWSNativeSDKInit/source/AWSNativeSDKInit.cpp @@ -25,6 +25,8 @@ namespace AWSNativeSDKInit #if defined(PLATFORM_SUPPORTS_AWS_NATIVE_SDK) void CustomizeSDKOptions(Aws::SDKOptions& options); void CustomizeShutdown(); + + void CopyCaCertBundle(); #endif } @@ -44,6 +46,8 @@ namespace AWSNativeSDKInit void InitializationManager::InitAwsApi() { s_initManager = AZ::Environment::CreateVariable(initializationManagerTag); + + Platform::CopyCaCertBundle(); } void InitializationManager::Shutdown() diff --git a/Code/Tools/AWSNativeSDKInit/source/Platform/Android/InitializeCerts_Android.cpp b/Code/Tools/AWSNativeSDKInit/source/Platform/Android/InitializeCerts_Android.cpp new file mode 100644 index 0000000000..67cdee7edc --- /dev/null +++ b/Code/Tools/AWSNativeSDKInit/source/Platform/Android/InitializeCerts_Android.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +// The AWS Native SDK AWSAllocator triggers a warning due to accessing members of std::allocator directly. +// AWSAllocator.h(70): warning C4996: 'std::allocator::pointer': warning STL4010: Various members of std::allocator are deprecated in +// C++17. Use std::allocator_traits instead of accessing these members directly. You can define +// _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received +// this warning. +AZ_PUSH_DISABLE_WARNING(4251 4996, "-Wunknown-warning-option") +#include +AZ_POP_DISABLE_WARNING +#include +#include +#include +#include + +namespace AWSNativeSDKInit +{ + namespace Platform + { + void CopyCaCertBundle() + { + AZStd::vector contents; + AZStd::string certificatePath = "@assets@/certificates/aws/cacert.pem"; + AZStd::string publicStoragePath = AZ::Android::Utils::GetAppPublicStoragePath(); + publicStoragePath.append("/certificates/aws/cacert.pem"); + + AZ::IO::FileIOBase* fileBase = AZ::IO::FileIOBase::GetInstance(); + + if (!fileBase->Exists(certificatePath.c_str())) + { + AZ_Error("AWSNativeSDKInit", false, "Certificate File(%s) does not exist.\n", certificatePath.c_str()); + } + + AZ::IO::HandleType fileHandle; + AZ::IO::Result fileResult = fileBase->Open(certificatePath.c_str(), AZ::IO::OpenMode::ModeRead, fileHandle); + + if (!fileResult) + { + AZ_Error("AWSNativeSDKInit", false, "Failed to open certificate file with result %i\n", fileResult.GetResultCode()); + } + + AZ::u64 fileSize = 0; + fileBase->Size(fileHandle, fileSize); + + if (fileSize == 0) + { + AZ_Error("AWSNativeSDKInit", false, "Given empty file(%s) as the certificate bundle.\n", certificatePath.c_str()); + } + + contents.resize(fileSize + 1); + fileResult = fileBase->Read(fileHandle, contents.data(), fileSize); + + if (!fileResult) + { + AZ_Error( + "AWSNativeSDKInit", false, "Failed to read from the certificate bundle(%s) with result code(%i).\n", certificatePath.c_str(), + fileResult.GetResultCode()); + } + + AZ_Printf("AWSNativeSDKInit", "Certificate bundle is read successfully from %s", certificatePath.c_str()); + + AZ::IO::HandleType outFileHandle; + + AZ::IO::Result outFileResult = fileBase->Open(publicStoragePath.c_str(), AZ::IO::OpenMode::ModeWrite, outFileHandle); + + if (!outFileResult) + { + AZ_Error("AWSNativeSDKInit", false, "Failed to open the certificate bundle with result %i\n", fileResult.GetResultCode()); + } + + AZ::IO::Result writeFileResult = fileBase->Write(outFileHandle, contents.data(), fileSize); + if (!writeFileResult) + { + AZ_Error("AWSNativeSDKInit", false, "Failed to write the certificate bundle with result %i\n", writeFileResult.GetResultCode()); + } + + fileBase->Close(fileHandle); + fileBase->Close(outFileHandle); + + AZ_Printf("AWSNativeSDKInit", "Certificate bundle successfully copied to %s", publicStoragePath.c_str()); + } + } // namespace Platform +} diff --git a/Code/Tools/AWSNativeSDKInit/source/Platform/Android/platform_android_files.cmake b/Code/Tools/AWSNativeSDKInit/source/Platform/Android/platform_android_files.cmake index 0ec1f30fea..6e0370dd42 100644 --- a/Code/Tools/AWSNativeSDKInit/source/Platform/Android/platform_android_files.cmake +++ b/Code/Tools/AWSNativeSDKInit/source/Platform/Android/platform_android_files.cmake @@ -7,4 +7,5 @@ set(FILES ../Common/Default/AWSNativeSDKInit_Default.cpp + InitializeCerts_Android.cpp ) diff --git a/Code/Tools/AWSNativeSDKInit/source/Platform/Common/Default/InitializeCerts_Null.cpp b/Code/Tools/AWSNativeSDKInit/source/Platform/Common/Default/InitializeCerts_Null.cpp new file mode 100644 index 0000000000..7981998327 --- /dev/null +++ b/Code/Tools/AWSNativeSDKInit/source/Platform/Common/Default/InitializeCerts_Null.cpp @@ -0,0 +1,16 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +namespace AWSNativeSDKInit +{ + namespace Platform + { + void CopyCaCertBundle() + { + } + } // namespace Platform +} // namespace AWSCore diff --git a/Code/Tools/AWSNativeSDKInit/source/Platform/Linux/platform_linux_files.cmake b/Code/Tools/AWSNativeSDKInit/source/Platform/Linux/platform_linux_files.cmake index 0ec1f30fea..6209d3faac 100644 --- a/Code/Tools/AWSNativeSDKInit/source/Platform/Linux/platform_linux_files.cmake +++ b/Code/Tools/AWSNativeSDKInit/source/Platform/Linux/platform_linux_files.cmake @@ -7,4 +7,5 @@ set(FILES ../Common/Default/AWSNativeSDKInit_Default.cpp + ../Common/Default/InitializeCerts_Null.cpp ) diff --git a/Code/Tools/AWSNativeSDKInit/source/Platform/Mac/platform_mac_files.cmake b/Code/Tools/AWSNativeSDKInit/source/Platform/Mac/platform_mac_files.cmake index 0ec1f30fea..6209d3faac 100644 --- a/Code/Tools/AWSNativeSDKInit/source/Platform/Mac/platform_mac_files.cmake +++ b/Code/Tools/AWSNativeSDKInit/source/Platform/Mac/platform_mac_files.cmake @@ -7,4 +7,5 @@ set(FILES ../Common/Default/AWSNativeSDKInit_Default.cpp + ../Common/Default/InitializeCerts_Null.cpp ) diff --git a/Code/Tools/AWSNativeSDKInit/source/Platform/Windows/platform_windows_files.cmake b/Code/Tools/AWSNativeSDKInit/source/Platform/Windows/platform_windows_files.cmake index 0ec1f30fea..6209d3faac 100644 --- a/Code/Tools/AWSNativeSDKInit/source/Platform/Windows/platform_windows_files.cmake +++ b/Code/Tools/AWSNativeSDKInit/source/Platform/Windows/platform_windows_files.cmake @@ -7,4 +7,5 @@ set(FILES ../Common/Default/AWSNativeSDKInit_Default.cpp + ../Common/Default/InitializeCerts_Null.cpp ) diff --git a/Code/Tools/AWSNativeSDKInit/source/Platform/iOS/platform_ios_files.cmake b/Code/Tools/AWSNativeSDKInit/source/Platform/iOS/platform_ios_files.cmake index 0ec1f30fea..6209d3faac 100644 --- a/Code/Tools/AWSNativeSDKInit/source/Platform/iOS/platform_ios_files.cmake +++ b/Code/Tools/AWSNativeSDKInit/source/Platform/iOS/platform_ios_files.cmake @@ -7,4 +7,5 @@ set(FILES ../Common/Default/AWSNativeSDKInit_Default.cpp + ../Common/Default/InitializeCerts_Null.cpp ) diff --git a/Gems/AWSClientAuth/Code/Source/AWSClientAuthSystemComponent.cpp b/Gems/AWSClientAuth/Code/Source/AWSClientAuthSystemComponent.cpp index c8c16cd26f..a6ba5812a1 100644 --- a/Gems/AWSClientAuth/Code/Source/AWSClientAuthSystemComponent.cpp +++ b/Gems/AWSClientAuth/Code/Source/AWSClientAuthSystemComponent.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -163,7 +164,11 @@ namespace AWSClientAuth void AWSClientAuthSystemComponent::OnSDKInitialized() { - Aws::Client::ClientConfiguration clientConfiguration; + AWSCore::AwsApiJobConfig* defaultConfig; + AWSCore::AWSCoreRequestBus::BroadcastResult(defaultConfig, &AWSCore::AWSCoreRequests::GetDefaultConfig); + Aws::Client::ClientConfiguration clientConfiguration = + defaultConfig ? defaultConfig->GetClientConfiguration() : Aws::Client::ClientConfiguration(); + AZStd::string region; AWSCore::AWSResourceMappingRequestBus::BroadcastResult(region, &AWSCore::AWSResourceMappingRequests::GetDefaultRegion); diff --git a/Gems/AWSClientAuth/Code/Tests/AWSClientAuthGemMock.h b/Gems/AWSClientAuth/Code/Tests/AWSClientAuthGemMock.h index cf6364fa00..dc9a84bc0a 100644 --- a/Gems/AWSClientAuth/Code/Tests/AWSClientAuthGemMock.h +++ b/Gems/AWSClientAuth/Code/Tests/AWSClientAuthGemMock.h @@ -113,6 +113,27 @@ namespace AWSClientAuthUnitTest MOCK_METHOD1(ReloadConfigFile, void(bool isReloadingConfigFileName)); }; + class AWSCoreRequestBusMock + : public AWSCore::AWSCoreRequestBus::Handler + { + public: + AWSCoreRequestBusMock() + { + AWSCore::AWSCoreRequestBus::Handler::BusConnect(); + + ON_CALL(*this, GetDefaultJobContext).WillByDefault(testing::Return(nullptr)); + ON_CALL(*this, GetDefaultConfig).WillByDefault(testing::Return(nullptr)); + } + + ~AWSCoreRequestBusMock() + { + AWSCore::AWSCoreRequestBus::Handler::BusDisconnect(); + } + + MOCK_METHOD0(GetDefaultJobContext, AZ::JobContext*()); + MOCK_METHOD0(GetDefaultConfig, AWSCore::AwsApiJobConfig*()); + }; + class HttpRequestorRequestBusMock : public HttpRequestor::HttpRequestorRequestBus::Handler { diff --git a/Gems/AWSClientAuth/Code/Tests/AWSClientAuthSystemComponentTest.cpp b/Gems/AWSClientAuth/Code/Tests/AWSClientAuthSystemComponentTest.cpp index 7a5ddc1f61..1b4fe3b3a1 100644 --- a/Gems/AWSClientAuth/Code/Tests/AWSClientAuthSystemComponentTest.cpp +++ b/Gems/AWSClientAuth/Code/Tests/AWSClientAuthSystemComponentTest.cpp @@ -161,6 +161,7 @@ public: testing::NiceMock *m_awsClientAuthSystemsComponent; testing::NiceMock *m_awsCoreSystemsComponent; testing::NiceMock m_awsResourceMappingRequestBusMock; + testing::NiceMock m_awsCoreRequestBusMock; AZ::Entity* m_entity = nullptr; }; @@ -176,6 +177,7 @@ TEST_F(AWSClientAuthSystemComponentTest, ActivateDeactivate_Success) EXPECT_CALL(*m_awsCoreSystemsComponent, Init()).Times(1).InSequence(s1); EXPECT_CALL(*m_awsClientAuthSystemsComponent, Init()).Times(1).InSequence(s1); EXPECT_CALL(*m_awsCoreSystemsComponent, Activate()).Times(1).InSequence(s1); + EXPECT_CALL(m_awsCoreRequestBusMock, GetDefaultConfig()).Times(1).InSequence(s1); EXPECT_CALL(m_awsResourceMappingRequestBusMock, GetDefaultRegion()).Times(1).InSequence(s1); EXPECT_CALL(*m_awsClientAuthSystemsComponent, Activate()).Times(1).InSequence(s1); diff --git a/Gems/AWSCore/Assets/Certificates/AWS/cacert.pem b/Gems/AWSCore/Assets/Certificates/AWS/cacert.pem new file mode 100644 index 0000000000..cb8f3ada5c --- /dev/null +++ b/Gems/AWSCore/Assets/Certificates/AWS/cacert.pem @@ -0,0 +1,4043 @@ +## +## Bundle of CA Root Certificates +## +## Certificate data from Mozilla as of: Wed Jan 18 04:12:05 2017 GMT +## +## This is a bundle of X.509 certificates of public Certificate Authorities +## (CA). These were automatically extracted from Mozilla's root certificates +## file (certdata.txt). This file can be found in the mozilla source tree: +## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt +## +## It contains the certificates in PEM format and therefore +## can be directly used with curl / libcurl / php_curl, or with +## an Apache+mod_ssl webserver for SSL client authentication. +## Just configure this file as the SSLCACertificateFile. +## +## Conversion done with mk-ca-bundle.pl version 1.27. +## SHA256: dffa79e6aa993f558e82884abf7bb54bf440ab66ee91d82a27a627f6f2a4ace4 +## + + +GlobalSign Root CA +================== +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx +GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds +b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV +BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD +VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa +DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc +THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb +Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP +c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX +gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF +AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj +Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG +j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH +hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC +X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +GlobalSign Root CA - R2 +======================= +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv +YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh +bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT +aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln +bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6 +ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp +s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN +S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL +TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C +ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i +YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN +BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp +9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu +01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7 +9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- + +Verisign Class 3 Public Primary Certification Authority - G3 +============================================================ +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy +dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1 +EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc +cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw +EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj +055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA +ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f +j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC +/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0 +xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa +t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== +-----END CERTIFICATE----- + +Entrust.net Premium 2048 Secure Server CA +========================================= +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u +ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp +bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV +BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx +NzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3 +d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl +MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u +ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL +Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr +hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW +nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi +VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo0IwQDAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJ +KoZIhvcNAQEFBQADggEBADubj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPy +T/4xmf3IDExoU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5bu/8j72gZyxKT +J1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+bYQLCIt+jerXmCHG8+c8eS9e +nNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/ErfF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- + +Baltimore CyberTrust Root +========================= +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE +ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li +ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC +SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs +dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME +uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB +UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C +G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9 +XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr +l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI +VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB +BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh +cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5 +hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa +Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H +RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +AddTrust Low-Value Services Root +================================ +-----BEGIN CERTIFICATE----- +MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRU +cnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQsw +CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBO +ZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY6 +54eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWr +oulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1 +Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJui +GMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8w +HQYDVR0OBBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQswCQYDVQQGEwJT +RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEw +HwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxt +ZBsfzQ3duQH6lmM0MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph +iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY +eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJlpz/+0WatC7xr +mYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vj +ccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= +-----END CERTIFICATE----- + +AddTrust External Root +====================== +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD +VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw +NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU +cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg +Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821 ++iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw +Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo +aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy +2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7 +7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL +VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk +VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB +IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl +j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355 +e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u +G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE----- + +AddTrust Public Services Root +============================= +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSAwHgYDVQQDExdBZGRU +cnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJ +BgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5l +dHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbu +nyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1i +d9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSG +Aa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAw +HM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0G +A1UdDgQWBBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29yazEgMB4G +A1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4 +JNojVhaTdt02KLmuG7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL ++YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao +GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh4SINhwBk/ox9 +Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9H +EufOX1362KqxMy3ZdvJOOjMMK7MtkAY= +-----END CERTIFICATE----- + +AddTrust Qualified Certificates Root +==================================== +-----BEGIN CERTIFICATE----- +MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSMwIQYDVQQDExpBZGRU +cnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcx +CzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ +IE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx +64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3 +KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1tUvznoD1o +L/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GR +wVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HU +MIHRMB0GA1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkwZzELMAkGA1UE +BhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29y +azEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBABmrder4i2VhlRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG +GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X +dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3P6CxB9bpT9ze +RXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDB +iFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5noxqE= +-----END CERTIFICATE----- + +Entrust Root Certification Authority +==================================== +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV +BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw +b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG +A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0 +MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu +MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu +Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v +dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz +A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww +Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68 +j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN +rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1 +MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH +hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM +Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa +v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS +W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 +tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +GeoTrust Global CA +================== +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK +Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw +MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j +LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo +BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet +8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc +T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU +vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk +DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q +zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4 +d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2 +mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p +XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm +Mw== +-----END CERTIFICATE----- + +GeoTrust Global CA 2 +==================== +-----BEGIN CERTIFICATE----- +MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwHhcNMDQwMzA0MDUw +MDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j +LjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDvPE1APRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/ +NTL8Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hLTytCOb1k +LUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL5mkWRxHCJ1kDs6ZgwiFA +Vvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7S4wMcoKK+xfNAGw6EzywhIdLFnopsk/b +HdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNH +K266ZUapEBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6tdEPx7 +srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv/NgdRN3ggX+d6Yvh +ZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywNA0ZF66D0f0hExghAzN4bcLUprbqL +OzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkC +x1YAzUm5s2x7UwQa4qjJqhIFI8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqF +H4z1Ir+rzoPz4iIprn2DQKi6bA== +-----END CERTIFICATE----- + +GeoTrust Universal CA +===================== +-----BEGIN CERTIFICATE----- +MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1 +MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu +Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t +JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e +RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs +7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d +8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V +qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga +Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB +Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu +KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08 +ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0 +XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB +hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc +aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2 +qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL +oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK +xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF +KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2 +DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK +xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU +p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI +P/rmMuGNG2+k5o7Y+SlIis5z/iw= +-----END CERTIFICATE----- + +GeoTrust Universal CA 2 +======================= +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0 +MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg +SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0 +DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17 +j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q +JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a +QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2 +WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP +20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn +ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC +SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG +8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2 ++/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E +BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z +dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ +4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+ +mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq +A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg +Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP +pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d +FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp +gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm +X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS +-----END CERTIFICATE----- + +Visa eCommerce Root +=================== +-----BEGIN CERTIFICATE----- +MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG +EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug +QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2 +WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm +VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv +bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL +F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b +RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0 +TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI +/k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs +GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG +MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc +CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW +YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz +zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu +YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt +398znM/jra6O1I7mT1GvFpLgXPYHDw== +-----END CERTIFICATE----- + +Certum Root CA +============== +-----BEGIN CERTIFICATE----- +MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQK +ExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQTAeFw0wMjA2MTExMDQ2Mzla +Fw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8u +by4xEjAQBgNVBAMTCUNlcnR1bSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6x +wS7TT3zNJc4YPk/EjG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdL +kKWoePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GIULdtlkIJ +89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapuOb7kky/ZR6By6/qmW6/K +Uz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUgAKpoC6EahQGcxEZjgoi2IrHu/qpGWX7P +NSzVttpd90gzFFS269lvzs2I1qsb2pY7HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq +hkiG9w0BAQUFAAOCAQEAuI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+ +GXYkHAQaTOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTgxSvg +GrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1qCjqTE5s7FCMTY5w/ +0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5xO/fIR/RpbxXyEV6DHpx8Uq79AtoS +qFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs6GAqm4VKQPNriiTsBhYscw== +-----END CERTIFICATE----- + +Comodo AAA Services root +======================== +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw +MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl +c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV +BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG +C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs +i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW +Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH +Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK +Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f +BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl +cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz +LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm +7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z +8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C +12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +Comodo Secure Services root +=========================== +-----BEGIN CERTIFICATE----- +MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAw +MDAwMFoXDTI4MTIzMTIzNTk1OVowfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFu +Y2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAi +BgNVBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPMcm3ye5drswfxdySRXyWP +9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3SHpR7LZQdqnXXs5jLrLxkU0C8j6ysNstc +rbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rC +oznl2yY4rYsK7hljxxwk3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3V +p6ea5EQz6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNVHQ4E +FgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w +gYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL1NlY3VyZUNlcnRpZmlj +YXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRwOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlm +aWNhdGVTZXJ2aWNlcy5jcmwwDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm +4J4oqF7Tt/Q05qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj +Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtIgKvcnDe4IRRL +DXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJaD61JlfutuC23bkpgHl9j6Pw +pCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDlizeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1H +RR3B7Hzs/Sk= +-----END CERTIFICATE----- + +Comodo Trusted Services root +============================ +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEw +MDAwMDBaFw0yODEyMzEyMzU5NTlaMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1h +bmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUw +IwYDVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWWfnJSoBVC21ndZHoa0Lh7 +3TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMtTGo87IvDktJTdyR0nAducPy9C1t2ul/y +/9c3S0pgePfw+spwtOpZqqPOSC+pw7ILfhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6 +juljatEPmsbS9Is6FARW1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsS +ivnkBbA7kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0GA1Ud +DgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21vZG9jYS5jb20vVHJ1c3RlZENlcnRp +ZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRodHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENl +cnRpZmljYXRlU2VydmljZXMuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8Ntw +uleGFTQQuS9/HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 +pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxISjBc/lDb+XbDA +BHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+xqFx7D+gIIxmOom0jtTYsU0l +R+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/AtyjcndBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O +9y5Xt5hwXsjEeLBi +-----END CERTIFICATE----- + +QuoVadis Root CA +================ +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE +ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz +MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp +cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD +EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk +J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL +F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL +YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen +AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w +PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y +ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7 +MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj +YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs +ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW +Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu +BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw +FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6 +tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo +fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul +LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x +gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi +5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi +5nrQNiOKSnQ2+Q== +-----END CERTIFICATE----- + +QuoVadis Root CA 2 +================== +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT +EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx +ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6 +XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk +lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB +lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy +lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt +66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn +wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh +D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy +BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie +J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud +DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU +a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv +Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3 +UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm +VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK ++JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW +IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1 +WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X +f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II +4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8 +VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- + +QuoVadis Root CA 3 +================== +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT +EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx +OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg +DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij +KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K +DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv +BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp +p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8 +nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX +MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM +Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz +uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT +BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj +YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB +BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD +VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4 +ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE +AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV +qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s +hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z +POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2 +Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp +8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC +bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu +g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p +vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr +qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- + +Security Communication Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP +U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw +HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP +U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw +8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM +DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX +5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd +DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2 +JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g +0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a +mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ +s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ +6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi +FL39vmwLAw== +-----END CERTIFICATE----- + +Sonera Class 2 Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG +U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw +NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh +IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3 +/Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT +dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG +f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P +tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH +nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT +XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt +0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI +cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph +Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx +EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH +llpwrN9M +-----END CERTIFICATE----- + +UTN USERFirst Hardware Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UE +BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl +IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAd +BgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgx +OTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0 +eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVz +ZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlI +wrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFd +tqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8 +i4fDidNdoI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjf +Pe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhbAgMBAAGjgbkw +gbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKFyXyYbKJhDlV0HN9WF +lp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNF +UkZpcnN0LUhhcmR3YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF +BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM +//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28GpgoiskliCE7/yMgUsogW +XecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2 +lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kn +iCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67 +nfhmqA== +-----END CERTIFICATE----- + +Camerfirma Chambers of Commerce Root +==================================== +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe +QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i +ZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAx +NjEzNDNaFw0zNzA5MzAxNjEzNDRaMH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZp +cm1hIFNBIENJRiBBODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3Jn +MSIwIAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0BAQEFAAOC +AQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtbunXF/KGIJPov7coISjlU +xFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0dBmpAPrMMhe5cG3nCYsS4No41XQEMIwRH +NaqbYE6gZj3LJgqcQKH0XZi/caulAGgq7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jW +DA+wWFjbw2Y3npuRVDM30pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFV +d9oKDMyXroDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIGA1Ud +EwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5jaGFtYmVyc2lnbi5v +cmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p26EpW1eLTXYGduHRooowDgYDVR0P +AQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hh +bWJlcnNpZ24ub3JnMCcGA1UdEgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYD +VR0gBFEwTzBNBgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz +aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEBAAxBl8IahsAi +fJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZdp0AJPaxJRUXcLo0waLIJuvvD +L8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wN +UPf6s+xCX6ndbcj0dc97wXImsQEcXCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/n +ADydb47kMgkdTXg0eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1 +erfutGWaIZDgqtCYvDi1czyL+Nw= +-----END CERTIFICATE----- + +Camerfirma Global Chambersign Root +================================== +-----BEGIN CERTIFICATE----- +MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe +QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i +ZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYx +NDE4WhcNMzcwOTMwMTYxNDE4WjB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJt +YSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEg +MB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUAA4IBDQAw +ggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0Mi+ITaFgCPS3CU6gSS9J +1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/sQJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8O +by4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpVeAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl +6DJWk0aJqCWKZQbua795B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c +8lCrEqWhz0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0TAQH/ +BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1iZXJzaWduLm9yZy9j +aGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4wTcbOX60Qq+UDpfqpFDAOBgNVHQ8B +Af8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAHMCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBj +aGFtYmVyc2lnbi5vcmcwKgYDVR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9y +ZzBbBgNVHSAEVDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh +bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0BAQUFAAOCAQEA +PDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUMbKGKfKX0j//U2K0X1S0E0T9Y +gOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXiryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJ +PJ7oKXqJ1/6v/2j1pReQvayZzKWGVwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4 +IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes +t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== +-----END CERTIFICATE----- + +XRamp Global CA Root +==================== +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE +BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj +dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx +HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg +U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu +IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx +foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE +zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs +AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry +xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap +oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC +AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc +/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n +nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz +8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +Go Daddy Class 2 CA +=================== +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY +VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG +A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g +RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD +ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv +2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32 +qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j +YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY +vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O +BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o +atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu +MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG +A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim +PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt +I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI +Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b +vZ8= +-----END CERTIFICATE----- + +Starfield Class 2 CA +==================== +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc +U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo +MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG +A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG +SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY +bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ +JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm +epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN +F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF +MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f +hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo +bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g +QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs +afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM +PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD +KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3 +QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +StartCom Certification Authority +================================ +-----BEGIN CERTIFICATE----- +MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu +ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 +NjM2WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk +LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg +U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y +o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ +Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d +eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt +2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z +6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ +osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ +untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc +UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT +37uMdBNSSwIDAQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE +FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9jZXJ0LnN0YXJ0 +Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3JsLnN0YXJ0Y29tLm9yZy9zZnNj +YS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFMBgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUH +AgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRw +Oi8vY2VydC5zdGFydGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYg +U3RhcnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlhYmlsaXR5 +LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2YgdGhlIFN0YXJ0Q29tIENl +cnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFpbGFibGUgYXQgaHR0cDovL2NlcnQuc3Rh +cnRjb20ub3JnL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilT +dGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOC +AgEAFmyZ9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8jhvh +3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUWFjgKXlf2Ysd6AgXm +vB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJzewT4F+irsfMuXGRuczE6Eri8sxHk +fY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3 +fsNrarnDy0RLrHiQi+fHLB5LEUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZ +EoalHmdkrQYuL6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq +yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuCO3NJo2pXh5Tl +1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6Vum0ABj6y6koQOdjQK/W/7HW/ +lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkyShNOsF/5oirpt9P/FlUQqmMGqz9IgcgA38coro +g14= +-----END CERTIFICATE----- + +Taiwan GRCA +=========== +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG +EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X +DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv +dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN +w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5 +BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O +1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO +htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov +J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7 +Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t +B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB +O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8 +lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV +HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2 +09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ +TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj +Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2 +Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU +D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz +DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk +Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk +7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ +CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy ++fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS +-----END CERTIFICATE----- + +Swisscom Root CA 1 +================== +-----BEGIN CERTIFICATE----- +MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQG +EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy +dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4 +MTgyMjA2MjBaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln +aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIIC +IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9m2BtRsiM +MW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdihFvkcxC7mlSpnzNApbjyF +NDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/TilftKaNXXsLmREDA/7n29uj/x2lzZAe +AR81sH8A25Bvxn570e56eqeqDFdvpG3FEzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkC +b6dJtDZd0KTeByy2dbcokdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn +7uHbHaBuHYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNFvJbN +cA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo19AOeCMgkckkKmUp +WyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjCL3UcPX7ape8eYIVpQtPM+GP+HkM5 +haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJWbjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNY +MUJDLXT5xp6mig/p/r+D5kNXJLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw +HQYDVR0hBBYwFDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j +BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzcK6FptWfUjNP9 +MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzfky9NfEBWMXrrpA9gzXrzvsMn +jgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7IkVh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQ +MbFamIp1TpBcahQq4FJHgmDmHtqBsfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4H +VtA4oJVwIHaM190e3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtl +vrsRls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ipmXeascCl +OS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HHb6D0jqTsNFFbjCYDcKF3 +1QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksfrK/7DZBaZmBwXarNeNQk7shBoJMBkpxq +nvy5JMWzFYJ+vq6VK+uxwNrjAWALXmmshFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCy +x/yP2FS1k2Kdzs9Z+z0YzirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMW +NY6E0F/6MBr1mmz0DlP5OlvRHA== +-----END CERTIFICATE----- + +DigiCert Assured ID Root CA +=========================== +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw +IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx +MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL +ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO +9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy +UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW +/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy +oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf +GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF +66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq +hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc +EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn +SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i +8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +DigiCert Global Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw +HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw +MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 +dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn +TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5 +BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H +4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y +7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB +o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm +8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF +BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr +EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt +tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886 +UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +DigiCert High Assurance EV Root CA +================================== +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw +KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw +MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ +MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu +Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t +Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS +OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3 +MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ +NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe +h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB +Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY +JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ +V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp +myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK +mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K +-----END CERTIFICATE----- + +Certplus Class 2 Primary CA +=========================== +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE +BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN +OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy +dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR +5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ +Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO +YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e +e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME +CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ +YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t +L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD +P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R +TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+ +7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW +//1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 +l7+ijrRU +-----END CERTIFICATE----- + +DST Root CA X3 +============== +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK +ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X +DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1 +cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT +rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9 +UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy +xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d +utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ +MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug +dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE +GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw +RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS +fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----END CERTIFICATE----- + +DST ACES CA X6 +============== +-----BEGIN CERTIFICATE----- +MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QxETAPBgNVBAsTCERTVCBBQ0VT +MRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0wMzExMjAyMTE5NThaFw0xNzExMjAyMTE5NTha +MFsxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UE +CxMIRFNUIEFDRVMxFzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPuktKe1jzI +DZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7gLFViYsx+tC3dr5BPTCa +pCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZHfAjIgrrep4c9oW24MFbCswKBXy314pow +GCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4aahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPy +MjwmR/onJALJfh1biEITajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rkc3Qu +Y29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnRy +dXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMtaW5kZXguaHRtbDAdBgNVHQ4EFgQU +CXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZIhvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V2 +5FYrnJmQ6AgwbN99Pe7lv7UkQIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6t +Fr8hlxCBPeP/h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq +nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpRrscL9yuwNwXs +vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3 +oKfN5XozNmr6mis= +-----END CERTIFICATE----- + +SwissSign Gold CA - G2 +====================== +-----BEGIN CERTIFICATE----- +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw +EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN +MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp +c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq +t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C +jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg +vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF +ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR +AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend +jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO +peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR +7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi +GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64 +OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm +5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr +44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf +Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m +Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp +mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk +vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf +KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br +NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj +viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ +-----END CERTIFICATE----- + +SwissSign Silver CA - G2 +======================== +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT +BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X +DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3 +aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG +9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644 +N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm ++/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH +6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu +MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h +qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5 +FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs +ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc +celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X +CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB +tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P +4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F +kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L +3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx +/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa +DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP +e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu +WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ +DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub +DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority +======================================== +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx +CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ +cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN +b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9 +nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge +RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt +tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI +hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K +Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN +NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa +Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG +1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= +-----END CERTIFICATE----- + +thawte Primary Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE +BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 +aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3 +MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg +SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv +KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT +FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs +oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ +1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc +q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K +aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p +afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF +AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE +uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89 +jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH +z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA== +-----END CERTIFICATE----- + +VeriSign Class 3 Public Primary Certification Authority - G5 +============================================================ +-----BEGIN CERTIFICATE----- +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE +BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO +ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk +IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln +biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh +dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt +YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz +j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD +Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ +Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r +fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv +Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG +SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+ +X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE +KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC +Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE +ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq +-----END CERTIFICATE----- + +SecureTrust CA +============== +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy +dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe +BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX +OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t +DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH +GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b +01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH +ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj +aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ +KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu +SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf +mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ +nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +Secure Global CA +================ +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH +bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg +MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg +Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx +YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ +bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g +8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV +HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi +0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn +oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA +MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+ +OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn +CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5 +3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +COMODO Certification Authority +============================== +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE +BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG +A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb +MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD +T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH ++7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww +xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV +4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA +1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI +rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k +b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC +AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP +OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc +IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN ++8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ== +-----END CERTIFICATE----- + +Network Solutions Certificate Authority +======================================= +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG +EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr +IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx +MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx +jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT +aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT +crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc +/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB +AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv +bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA +A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q +4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/ +GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD +ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- + +WellsSecure Public Root Certificate Authority +============================================= +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoM +F1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYw +NAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN +MDcxMjEzMTcwNzU0WhcNMjIxMjE0MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dl +bGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYD +VQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+rWxxTkqxtnt3CxC5FlAM1 +iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjUDk/41itMpBb570OYj7OeUt9tkTmPOL13 +i0Nj67eT/DBMHAGTthP796EfvyXhdDcsHqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8 +bJVhHlfXBIEyg1J55oNjz7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiB +K0HmOFafSZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/SlwxlAgMB +AAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwu +cGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBQm +lRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0jBIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGB +i6SBiDCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRww +GgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg +Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEBALkVsUSRzCPI +K0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd/ZDJPHV3V3p9+N701NX3leZ0 +bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pBA4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSlj +qHyita04pO2t/caaH/+Xc/77szWnk4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+es +E2fDbbFwRnzVlhE9iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJ +tylv2G0xffX8oRAHh84vWdw+WNs= +-----END CERTIFICATE----- + +COMODO ECC Certification Authority +================================== +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC +R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE +ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix +GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X +4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni +wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG +FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA +U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +Security Communication EV RootCA1 +================================= +-----BEGIN CERTIFICATE----- +MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMhU2VjdXJpdHkgQ29tbXVuaWNh +dGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIzMloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UE +BhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNl +Y3VyaXR5IENvbW11bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSERMqm4miO +/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gOzXppFodEtZDkBp2uoQSX +WHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4z +ZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDFMxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4 +bepJz11sS6/vmsJWXMY1VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK +9U2vP9eCOKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG +SIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HWtWS3irO4G8za+6xm +iEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZq51ihPZRwSzJIxXYKLerJRO1RuGG +Av8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDbEJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnW +mHyojf6GPgcWkuF75x3sM3Z+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEW +T1MKZPlO9L9OVL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490 +-----END CERTIFICATE----- + +OISTE WISeKey Global Root GA CA +=============================== +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE +BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG +A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH +bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD +VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw +IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5 +IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9 +Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg +Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD +d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ +/yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R +LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ +KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm +MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4 ++vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa +hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY +okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0= +-----END CERTIFICATE----- + +Microsec e-Szigno Root CA +========================= +-----BEGIN CERTIFICATE----- +MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAwcjELMAkGA1UE +BhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNyb3NlYyBMdGQuMRQwEgYDVQQL +EwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0 +MDYxMjI4NDRaFw0xNzA0MDYxMjI4NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVz +dDEWMBQGA1UEChMNTWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMT +GU1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2uuO/TEdyB5s87lozWbxXG +d36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/N +oqdNAoI/gqyFxuEPkEeZlApxcpMqyabAvjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjc +QR/Ji3HWVBTji1R4P770Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJ +PqW+jqpx62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcBAQRb +MFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3AwLQYIKwYBBQUHMAKG +IWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAPBgNVHRMBAf8EBTADAQH/MIIBcwYD +VR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIBAQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3 +LmUtc3ppZ25vLmh1L1NaU1ovMIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0A +dAB2AOEAbgB5ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn +AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABTAHoAbwBsAGcA +4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABhACAAcwB6AGUAcgBpAG4AdAAg +AGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABoAHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMA +egBpAGcAbgBvAC4AaAB1AC8AUwBaAFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6 +Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NO +PU1pY3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxPPU1pY3Jv +c2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5h +cnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuBEGluZm9AZS1zemlnbm8uaHWkdzB1MSMw +IQYDVQQDDBpNaWNyb3NlYyBlLVN6aWduw7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhT +WjEWMBQGA1UEChMNTWljcm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhV +MIGsBgNVHSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJIVTER +MA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDASBgNVBAsTC2UtU3pp +Z25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBSb290IENBghEAzLjnv04pGv2i3Gal +HCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMT +nGZjWS7KXHAM/IO8VbH0jgdsZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FE +aGAHQzAxQmHl7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a +86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfRhUZLphK3dehK +yVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/MPMMNz7UwiiAc7EBt51alhQB +S6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU= +-----END CERTIFICATE----- + +Certigna +======== +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw +EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3 +MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI +Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q +XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH +GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p +ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg +DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf +Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ +tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ +BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J +SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA +hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+ +ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu +PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY +1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- + +Deutsche Telekom Root CA 2 +========================== +-----BEGIN CERTIFICATE----- +MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT +RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG +A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5 +MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G +A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS +b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5 +bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI +KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY +AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK +Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV +jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV +HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr +E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy +zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8 +rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G +dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU +Cm26OWMohpLzGITY+9HPBVZkVw== +-----END CERTIFICATE----- + +Cybertrust Global Root +====================== +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li +ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4 +MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD +ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA ++Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW +0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL +AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin +89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT +8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2 +MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G +A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO +lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi +5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2 +hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T +X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW +WL1WMRJOEcgh4LMRkWXbtKaIOM5V +-----END CERTIFICATE----- + +ePKI Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG +EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx +MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq +MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs +IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi +lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv +qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX +12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O +WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+ +ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao +lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/ +vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi +Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi +MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0 +1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq +KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV +xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP +NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r +GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE +xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx +gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy +sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD +BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3 +============================================================================================================================= +-----BEGIN CERTIFICATE----- +MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRSMRgwFgYDVQQH +DA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJpbGltc2VsIHZlIFRla25vbG9q +aWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSwVEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ry +b25payB2ZSBLcmlwdG9sb2ppIEFyYcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNV +BAsMGkthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUg +S8O2ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAeFw0wNzA4 +MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIxGDAWBgNVBAcMD0dlYnpl +IC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmlsaW1zZWwgdmUgVGVrbm9sb2ppayBBcmHF +n3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBUQUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZl +IEtyaXB0b2xvamkgQXJhxZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2Ft +dSBTZXJ0aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7ZrIFNl +cnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4hgb46ezzb8R1Sf1n68yJMlaCQvEhO +Eav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yKO7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1 +xnnRFDDtG1hba+818qEhTsXOfJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR +6Oqeyjh1jmKwlZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL +hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQIDAQABo0IwQDAd +BgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmPNOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4 +N5EY3ATIZJkrGG2AA1nJrvhY0D7twyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLT +y9LQQfMmNkqblWwM7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYh +LBOhgLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5noN+J1q2M +dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI= +-----END CERTIFICATE----- + +certSIGN ROOT CA +================ +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD +VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa +Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE +CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I +JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH +rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2 +ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD +0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943 +AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B +Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB +AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8 +SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0 +x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt +vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz +TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +CNNIC ROOT +========== +-----BEGIN CERTIFICATE----- +MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJDTjEOMAwGA1UE +ChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2MDcwOTE0WhcNMjcwNDE2MDcw +OTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1Qw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzD +o+/hn7E7SIX1mlwhIhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tiz +VHa6dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZOV/kbZKKT +VrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrCGHn2emU1z5DrvTOTn1Or +czvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gNv7Sg2Ca+I19zN38m5pIEo3/PIKe38zrK +y5nLAgMBAAGjczBxMBEGCWCGSAGG+EIBAQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscC +wQ7vptU7ETAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991S +lgrHAsEO76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnKOOK5 +Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvHugDnuL8BV8F3RTIM +O/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7HgviyJA/qIYM/PmLXoXLT1tLYhFHxUV8 +BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fLbuXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2 +G8kS1sHNzYDzAgE8yGnLRUhj2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5m +mxE= +-----END CERTIFICATE----- + +ApplicationCA - Japanese Government +=================================== +-----BEGIN CERTIFICATE----- +MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEcMBoGA1UEChMT +SmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRpb25DQTAeFw0wNzEyMTIxNTAw +MDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYTAkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zl +cm5tZW50MRYwFAYDVQQLEw1BcHBsaWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAp23gdE6Hj6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4 +fl+Kf5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55IrmTwcrN +wVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cwFO5cjFW6WY2H/CPek9AE +jP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDihtQWEjdnjDuGWk81quzMKq2edY3rZ+nYVu +nyoKb58DKTCXKB28t89UKU5RMfkntigm/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRU +WssmP3HMlEYNllPqa0jQk/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNV +BAYTAkpQMRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOCseOD +vOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADlqRHZ3ODrs +o2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJhyzjVOGjprIIC8CFqMjSnHH2HZ9g +/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYD +io+nEhEMy/0/ecGc/WLuo89UDNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmW +dupwX3kSa+SjB1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL +rosot4LKGAfmt1t06SAZf7IbiVQ= +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority - G3 +============================================= +-----BEGIN CERTIFICATE----- +MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE +BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0 +IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy +eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz +NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo +YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT +LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j +K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE +c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C +IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu +dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr +2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9 +cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE +Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD +AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s +t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt +-----END CERTIFICATE----- + +thawte Primary Root CA - G2 +=========================== +-----BEGIN CERTIFICATE----- +MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC +VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu +IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg +Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV +MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG +b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt +IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS +LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5 +8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU +mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN +G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K +rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== +-----END CERTIFICATE----- + +thawte Primary Root CA - G3 +=========================== +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE +BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 +aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w +ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh +d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD +VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG +A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At +P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC ++BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY +7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW +vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ +KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK +A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu +t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC +8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm +er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A= +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority - G2 +============================================= +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu +Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1 +OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg +MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl +b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG +BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc +KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+ +EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m +ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2 +npaqBA+K +-----END CERTIFICATE----- + +VeriSign Universal Root Certification Authority +=============================================== +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE +BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO +ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk +IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u +IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj +1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP +MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72 +9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I +AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR +tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G +CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O +a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3 +Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx +Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx +P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P +wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4 +mJO37M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- + +VeriSign Class 3 Public Primary Certification Authority - G4 +============================================================ +-----BEGIN CERTIFICATE----- +MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC +VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3 +b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz +ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU +cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo +b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5 +IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8 +Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz +rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw +HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u +Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD +A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx +AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== +-----END CERTIFICATE----- + +NetLock Arany (Class Gold) Főtanúsítvány +======================================== +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G +A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610 +dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB +cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx +MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO +ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6 +c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu +0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw +/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk +H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw +fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1 +neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW +qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta +YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna +NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu +dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +Staat der Nederlanden Root CA - G2 +================================== +-----BEGIN CERTIFICATE----- +MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE +CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g +Um9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC +TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l +ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ +5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn +vWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj +CwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil +e7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR +OME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI +CT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65 +48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi +trzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737 +qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB +AAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC +ARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA +A4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz ++51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj +f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN +kqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk +CpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF +URmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb +CG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h +oKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV +IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm +66+KAQ== +-----END CERTIFICATE----- + +Hongkong Post Root CA 1 +======================= +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT +DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx +NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n +IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 +ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr +auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh +qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY +V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV +HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i +h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio +l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei +IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps +T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT +c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== +-----END CERTIFICATE----- + +SecureSign RootCA11 +=================== +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi +SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS +b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw +KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1 +cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL +TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO +wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq +g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP +O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA +bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX +t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh +OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r +bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ +Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01 +y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061 +lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +ACEDICOM Root +============= +-----BEGIN CERTIFICATE----- +MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UEAwwNQUNFRElD +T00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMB4XDTA4 +MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEWMBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoG +A1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHk +WLn709gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7XBZXehuD +YAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5PGrjm6gSSrj0RuVFCPYew +MYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAKt0SdE3QrwqXrIhWYENiLxQSfHY9g5QYb +m8+5eaA9oiM/Qj9r+hwDezCNzmzAv+YbX79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbk +HQl/Sog4P75n/TSW9R28MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTT +xKJxqvQUfecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI2Sf2 +3EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyHK9caUPgn6C9D4zq9 +2Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEaeZAwUswdbxcJzbPEHXEUkFDWug/Fq +TYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz +4SsrSbbXc6GqlPUB53NlTKxQMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU +9QHnc2VMrFAwRAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv +bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWImfQwng4/F9tqg +aHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3gvoFNTPhNahXwOf9jU8/kzJP +eGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKeI6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1Pwk +zQSulgUV1qzOMPPKC8W64iLgpq0i5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1 +ThCojz2GuHURwCRiipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oI +KiMnMCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZo5NjEFIq +nxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6zqylfDJKZ0DcMDQj3dcE +I2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacNGHk0vFQYXlPKNFHtRQrmjseCNj6nOGOp +MCwXEGCSn1WHElkQwg9naRHMTh5+Spqtr0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3o +tkYNbn5XOmeUwssfnHdKZ05phkOTOPu220+DkdRgfks+KzgHVZhepA== +-----END CERTIFICATE----- + +Microsec e-Szigno Root CA 2009 +============================== +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER +MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv +c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE +BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt +U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA +fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG +0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA +pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm +1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC +AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf +QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE +FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o +lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX +I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02 +yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi +LXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +GlobalSign Root CA - R3 +======================= +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv +YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh +bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT +aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln +bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt +iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ +0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3 +rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl +OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2 +xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7 +lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8 +EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E +bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18 +YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r +kpeDMdmztcpHWD9f +-----END CERTIFICATE----- + +Autoridad de Certificacion Firmaprofesional CIF A62634068 +========================================================= +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA +BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 +MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw +QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB +NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD +Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P +B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY +7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH +ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI +plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX +MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX +LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK +bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU +vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud +EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH +DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA +bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx +ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx +51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk +R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP +T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f +Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl +osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR +crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR +saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD +KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi +6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- + +Izenpe.com +========== +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG +EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz +MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu +QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ +03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK +ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU ++zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC +PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT +OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK +F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK +0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+ +0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB +leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID +AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+ +SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG +NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O +BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l +Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga +kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q +hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs +g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5 +aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5 +nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC +ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo +Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z +WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- + +Chambers of Commerce Root - 2008 +================================ +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD +MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv +bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu +QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy +Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl +ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF +EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl +cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA +XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj +h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/ +ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk +NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g +D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331 +lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ +0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2 +EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI +G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ +BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh +bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh +bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC +CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH +AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1 +wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH +3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU +RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6 +M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1 +YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF +9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK +zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG +nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ +-----END CERTIFICATE----- + +Global Chambersign Root - 2008 +============================== +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD +MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv +bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu +QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx +NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg +Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ +QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf +VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf +XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0 +ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB +/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA +TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M +H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe +Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF +HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB +AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT +BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE +BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm +aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm +aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp +1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0 +dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG +/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6 +ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s +dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg +9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH +foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du +qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr +P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq +c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----END CERTIFICATE----- + +Go Daddy Root Certificate Authority - G2 +======================================== +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu +MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G +A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq +9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD ++qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd +fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl +NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9 +BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac +vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r +5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV +N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1 +-----END CERTIFICATE----- + +Starfield Root Certificate Authority - G2 +========================================= +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 +eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw +DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg +VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB +dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv +W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs +bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk +N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf +ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU +JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol +TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx +4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw +F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ +c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +Starfield Services Root Certificate Authority - G2 +================================================== +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl +IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT +dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg +Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2 +h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa +hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP +LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB +rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG +SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP +E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy +xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza +YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6 +-----END CERTIFICATE----- + +AffirmTrust Commercial +====================== +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw +MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly +bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb +DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV +C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6 +BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww +MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV +HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG +hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi +qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv +0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh +sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +AffirmTrust Networking +====================== +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw +MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly +bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE +Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI +dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24 +/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb +h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV +HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu +UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6 +12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23 +WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9 +/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +AffirmTrust Premium +=================== +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy +OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy +dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn +BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV +5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs ++7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd +GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R +p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI +S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04 +6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5 +/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo ++Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv +MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC +6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S +L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK ++4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV +BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg +IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60 +g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb +zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw== +-----END CERTIFICATE----- + +AffirmTrust Premium ECC +======================= +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV +BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx +MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U +cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ +N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW +BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK +BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X +57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM +eQ== +-----END CERTIFICATE----- + +Certum Trusted Network CA +========================= +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK +ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy +MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU +ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC +l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J +J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4 +fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0 +cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB +Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw +DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj +jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1 +mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj +Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +Certinomis - Autorité Racine +============================ +-----BEGIN CERTIFICATE----- +MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjETMBEGA1UEChMK +Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAkBgNVBAMMHUNlcnRpbm9taXMg +LSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkG +A1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYw +JAYDVQQDDB1DZXJ0aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jYF1AMnmHa +wE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N8y4oH3DfVS9O7cdxbwly +Lu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWerP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw +2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92N +jMD2AR5vpTESOH2VwnHu7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9q +c1pkIuVC28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6lSTC +lrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1Enn1So2+WLhl+HPNb +xxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB0iSVL1N6aaLwD4ZFjliCK0wi1F6g +530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql095gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna +4NH4+ej9Uji29YnfAgMBAAGjWzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBQNjLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ +KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9sov3/4gbIOZ/x +WqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZMOH8oMDX/nyNTt7buFHAAQCva +R6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40 +nJ+U8/aGH88bc62UeYdocMMzpXDn2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1B +CxMjidPJC+iKunqjo3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjv +JL1vnxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG5ERQL1TE +qkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWqpdEdnV1j6CTmNhTih60b +WfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZbdsLLO7XSAPCjDuGtbkD326C00EauFddE +wk01+dIL8hf2rGbVJLJP0RyZwG71fet0BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/ +vgt2Fl43N+bYdJeimUV5 +-----END CERTIFICATE----- + +TWCA Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ +VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG +EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB +IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx +QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC +oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP +4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r +y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG +9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC +mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW +QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY +T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny +Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +Security Communication RootCA2 +============================== +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh +dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC +SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy +aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++ ++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R +3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV +spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K +EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8 +QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB +CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj +u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk +3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q +tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 +mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +EC-ACC +====== +-----BEGIN CERTIFICATE----- +MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE +BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w +ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD +VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE +CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT +BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7 +MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt +SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl +Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh +cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK +w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT +ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4 +HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a +E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw +0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD +VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0 +Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l +dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ +lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa +Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe +l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2 +E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D +5EI= +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions RootCA 2011 +======================================================= +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT +O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y +aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z +IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT +AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z +IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo +IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI +1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa +71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u +8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH +3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/ +MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8 +MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu +b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt +XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD +/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N +7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----END CERTIFICATE----- + +Actalis Authentication Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM +BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE +AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky +MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz +IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ +wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa +by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6 +zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f +YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2 +oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l +EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7 +hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8 +EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5 +jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY +iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI +WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0 +JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx +K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+ +Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC +4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo +2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz +lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem +OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9 +vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +Trustis FPS Root CA +=================== +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG +EwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290 +IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV +BAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ +RUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk +H5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa +cY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt +o3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA +AaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd +BgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c +GE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC +yinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P +8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV +l/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl +iB6XzCGcKQENZetX2fNXlrtIzYE= +-----END CERTIFICATE----- + +StartCom Certification Authority +================================ +-----BEGIN CERTIFICATE----- +MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu +ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 +NjM3WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk +LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg +U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y +o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ +Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d +eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt +2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z +6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ +osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ +untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc +UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT +37uMdBNSSwIDAQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFulF2mHMMo0aEPQ +Qa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCCATgwLgYIKwYBBQUHAgEWImh0 +dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cu +c3RhcnRzc2wuY29tL2ludGVybWVkaWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENv +bW1lcmNpYWwgKFN0YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0 +aGUgc2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93d3cuc3RhcnRzc2wuY29t +L3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBG +cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5 +fPGFf59Jb2vKXfuM/gTFwWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWm +N3PH/UvSTa0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst0OcN +Org+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNcpRJvkrKTlMeIFw6T +tn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKlCcWw0bdT82AUuoVpaiF8H3VhFyAX +e2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVFP0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA +2MFrLH9ZXF2RsXAiV+uKa0hK1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBs +HvUwyKMQ5bLmKhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE +JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ8dCAWZvLMdib +D4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnmfyWl8kgAwKQB2j8= +-----END CERTIFICATE----- + +StartCom Certification Authority G2 +=================================== +-----BEGIN CERTIFICATE----- +MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +RzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UE +ChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8O +o1XJJZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsDvfOpL9HG +4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnooD/Uefyf3lLE3PbfHkffi +Aez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/Q0kGi4xDuFby2X8hQxfqp0iVAXV16iul +Q5XqFYSdCI0mblWbq9zSOdIxHWDirMxWRST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbs +O+wmETRIjfaAKxojAuuKHDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8H +vKTlXcxNnw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM0D4L +nMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/iUUjXuG+v+E5+M5iS +FGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9Ha90OrInwMEePnWjFqmveiJdnxMa +z6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHgTuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJ +KoZIhvcNAQELBQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K +2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfXUfEpY9Z1zRbk +J4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl6/2o1PXWT6RbdejF0mCy2wl+ +JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG +/+gyRr61M3Z3qAFdlsHB1b6uJcDJHgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTc +nIhT76IxW1hPkWLIwpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/Xld +blhYXzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5lIxKVCCIc +l85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoohdVddLHRDiBYmxOlsGOm +7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulrso8uBtjRkcfGEvRM/TAXw8HaOFvjqerm +obp573PYtlNXLfbQ4ddI +-----END CERTIFICATE----- + +Buypass Class 2 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X +DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1 +g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn +9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b +/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU +CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff +awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI +zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn +Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX +Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs +M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI +osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S +aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd +DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD +LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0 +oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC +wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS +CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN +rJgWVqA= +-----END CERTIFICATE----- + +Buypass Class 3 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X +DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH +sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR +5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh +7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ +ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH +2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV +/afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ +RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA +Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq +j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G +uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG +Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8 +ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2 +KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz +6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug +UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe +eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi +Cp/HuZc= +-----END CERTIFICATE----- + +T-TeleSec GlobalRoot Class 3 +============================ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM +IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU +cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx +MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz +dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD +ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK +9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU +NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF +iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W +0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr +AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb +fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT +ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h +P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw== +-----END CERTIFICATE----- + +EE Certification Centre Root CA +=============================== +-----BEGIN CERTIFICATE----- +MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG +EwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEoMCYGA1UEAwwfRUUgQ2Vy +dGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIw +MTAxMDMwMTAxMDMwWhgPMjAzMDEyMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlB +UyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRy +ZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUyeuuOF0+W2Ap7kaJjbMeM +TC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvObntl8jixwKIy72KyaOBhU8E2lf/slLo2 +rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIwWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw +93X2PaRka9ZP585ArQ/dMtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtN +P2MbRMNE1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/zQas8fElyalL1BSZ +MEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEF +BQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEFBQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+Rj +xY6hUFaTlrg4wCQiZrxTFGGVv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqM +lIpPnTX/dqQGE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u +uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU +3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/vGVCJYMzpJJUPwssd8m92kMfM +dcGWxZ0= +-----END CERTIFICATE----- + +TURKTRUST Certificate Services Provider Root 2007 +================================================= +-----BEGIN CERTIFICATE----- +MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP +MA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg +QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4X +DTA3MTIyNTE4MzcxOVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxl +a3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMCVFIxDzAN +BgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp +bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4gKGMpIEFyYWzEsWsgMjAwNzCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9N +YvDdE3ePYakqtdTyuTFYKTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQv +KUmi8wUG+7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveGHtya +KhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6PIzdezKKqdfcYbwnT +rqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M733WB2+Y8a+xwXrXgTW4qhe04MsC +AwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHkYb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/s +Px+EnWVUXKgWAkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I +aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5mxRZNTZPz/OO +Xl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsaXRik7r4EW5nVcV9VZWRi1aKb +BFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZqxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAK +poRq0Tl9 +-----END CERTIFICATE----- + +D-TRUST Root Class 3 CA 2 2009 +============================== +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTAe +Fw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NThaME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxE +LVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOAD +ER03UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42tSHKXzlA +BF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9RySPocq60vFYJfxLLHLGv +KZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsMlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7z +p+hnUquVH+BGPtikw8paxTGA6Eian5Rp/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUC +AwEAAaOCARowggEWMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ +4PGEMA4GA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVjdG9y +eS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUyMENBJTIwMiUyMDIw +MDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwQ6BBoD+G +PWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAw +OS5jcmwwDQYJKoZIhvcNAQELBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm +2H6NMLVwMeniacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4KzCUqNQT4YJEV +dT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8PIWmawomDeCTmGCufsYkl4ph +X5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3YJohw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +D-TRUST Root Class 3 CA 2 EV 2009 +================================= +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw +OTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUwNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw +OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfS +egpnljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM03TP1YtHh +zRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6ZqQTMFexgaDbtCHu39b+T +7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lRp75mpoo6Kr3HGrHhFPC+Oh25z1uxav60 +sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure35 +11H3a6UCAwEAAaOCASQwggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyv +cop9NteaHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFwOi8v +ZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xhc3MlMjAzJTIwQ0El +MjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRp +b25saXN0MEagRKBChkBodHRwOi8vd3d3LmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xh +c3NfM19jYV8yX2V2XzIwMDkuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+ +PPoeUSbrh/Yp3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNFCSuGdXzfX2lX +ANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7naxpeG0ILD5EJt/rDiZE4OJudA +NCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqXKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVv +w9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +PSCProcert +========== +-----BEGIN CERTIFICATE----- +MIIJhjCCB26gAwIBAgIBCzANBgkqhkiG9w0BAQsFADCCAR4xPjA8BgNVBAMTNUF1dG9yaWRhZCBk +ZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9sYW5vMQswCQYDVQQGEwJWRTEQ +MA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlzdHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lz +dGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBl +cmludGVuZGVuY2lhIGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUw +IwYJKoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyODE2NTEwMFoXDTIw +MTIyNTIzNTk1OVowgdExJjAkBgkqhkiG9w0BCQEWF2NvbnRhY3RvQHByb2NlcnQubmV0LnZlMQ8w +DQYDVQQHEwZDaGFjYW8xEDAOBgNVBAgTB01pcmFuZGExKjAoBgNVBAsTIVByb3ZlZWRvciBkZSBD +ZXJ0aWZpY2Fkb3MgUFJPQ0VSVDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZp +Y2FjaW9uIEVsZWN0cm9uaWNhMQswCQYDVQQGEwJWRTETMBEGA1UEAxMKUFNDUHJvY2VydDCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANW39KOUM6FGqVVhSQ2oh3NekS1wwQYalNo97BVC +wfWMrmoX8Yqt/ICV6oNEolt6Vc5Pp6XVurgfoCfAUFM+jbnADrgV3NZs+J74BCXfgI8Qhd19L3uA +3VcAZCP4bsm+lU/hdezgfl6VzbHvvnpC2Mks0+saGiKLt38GieU89RLAu9MLmV+QfI4tL3czkkoh +RqipCKzx9hEC2ZUWno0vluYC3XXCFCpa1sl9JcLB/KpnheLsvtF8PPqv1W7/U0HU9TI4seJfxPmO +EO8GqQKJ/+MMbpfg353bIdD0PghpbNjU5Db4g7ayNo+c7zo3Fn2/omnXO1ty0K+qP1xmk6wKImG2 +0qCZyFSTXai20b1dCl53lKItwIKOvMoDKjSuc/HUtQy9vmebVOvh+qBa7Dh+PsHMosdEMXXqP+UH +0quhJZb25uSgXTcYOWEAM11G1ADEtMo88aKjPvM6/2kwLkDd9p+cJsmWN63nOaK/6mnbVSKVUyqU +td+tFjiBdWbjxywbk5yqjKPK2Ww8F22c3HxT4CAnQzb5EuE8XL1mv6JpIzi4mWCZDlZTOpx+FIyw +Bm/xhnaQr/2v/pDGj59/i5IjnOcVdo/Vi5QTcmn7K2FjiO/mpF7moxdqWEfLcU8UC17IAggmosvp +r2uKGcfLFFb14dq12fy/czja+eevbqQ34gcnAgMBAAGjggMXMIIDEzASBgNVHRMBAf8ECDAGAQH/ +AgEBMDcGA1UdEgQwMC6CD3N1c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAz +Ni0wMB0GA1UdDgQWBBRBDxk4qpl/Qguk1yeYVKIXTC1RVDCCAVAGA1UdIwSCAUcwggFDgBStuyId +xuDSAaj9dlBSk+2YwU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0b3JpZGFkIGRlIENlcnRp +ZmljYWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xhbm8xCzAJBgNVBAYTAlZFMRAwDgYDVQQH +EwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0cml0byBDYXBpdGFsMTYwNAYDVQQKEy1TaXN0ZW1hIE5h +Y2lvbmFsIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5k +ZW5jaWEgZGUgU2VydmljaW9zIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkqhkiG +9w0BCQEWFmFjcmFpekBzdXNjZXJ0ZS5nb2IudmWCAQowDgYDVR0PAQH/BAQDAgEGME0GA1UdEQRG +MESCDnByb2NlcnQubmV0LnZloBUGBWCGXgIBoAwMClBTQy0wMDAwMDKgGwYFYIZeAgKgEgwQUklG +LUotMzE2MzUzNzMtNzB2BgNVHR8EbzBtMEagRKBChkBodHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52 +ZS9sY3IvQ0VSVElGSUNBRE8tUkFJWi1TSEEzODRDUkxERVIuY3JsMCOgIaAfhh1sZGFwOi8vYWNy +YWl6LnN1c2NlcnRlLmdvYi52ZTA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly9v +Y3NwLnN1c2NlcnRlLmdvYi52ZTBBBgNVHSAEOjA4MDYGBmCGXgMBAjAsMCoGCCsGAQUFBwIBFh5o +dHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9kcGMwDQYJKoZIhvcNAQELBQADggIBACtZ6yKZu4Sq +T96QxtGGcSOeSwORR3C7wJJg7ODU523G0+1ng3dS1fLld6c2suNUvtm7CpsR72H0xpkzmfWvADmN +g7+mvTV+LFwxNG9s2/NkAZiqlCxB3RWGymspThbASfzXg0gTB1GEMVKIu4YXx2sviiCtxQuPcD4q +uxtxj7mkoP3YldmvWb8lK5jpY5MvYB7Eqvh39YtsL+1+LrVPQA3uvFd359m21D+VJzog1eWuq2w1 +n8GhHVnchIHuTQfiSLaeS5UtQbHh6N5+LwUeaO6/u5BlOsju6rEYNxxik6SgMexxbJHmpHmJWhSn +FFAFTKQAVzAswbVhltw+HoSvOULP5dAssSS830DD7X9jSr3hTxJkhpXzsOfIt+FTvZLm8wyWuevo +5pLtp4EJFAv8lXrPj9Y0TzYS3F7RNHXGRoAvlQSMx4bEqCaJqD8Zm4G7UaRKhqsLEQ+xrmNTbSjq +3TNWOByyrYDT13K9mmyZY+gAu0F2BbdbmRiKw7gSXFbPVgx96OLP7bx0R/vu0xdOIk9W/1DzLuY5 +poLWccret9W6aAjtmcz9opLLabid+Qqkpj5PkygqYWwHJgD/ll9ohri4zspV4KuxPX+Y1zMOWj3Y +eMLEYC/HYvBhkdI4sPaeVdtAgAUSM84dkpvRabP/v/GSCmE1P93+hvS84Bpxs2Km +-----END CERTIFICATE----- + +China Internet Network Information Center EV Certificates Root +============================================================== +-----BEGIN CERTIFICATE----- +MIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyMUcwRQYDVQQDDD5D +aGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0aW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMg +Um9vdDAeFw0xMDA4MzEwNzExMjVaFw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAG +A1UECgwpQ2hpbmEgSW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMM +PkNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRpZmljYXRl +cyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z7r07eKpkQ0H1UN+U8i6y +jUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA//DdmEEbK40ctb3B75aDFk4Zv6dOtouSCV +98YPjUesWgbdYavi7NifFy2cyjw1l1VxzUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2H +klY0bBoQCxfVWhyXWIQ8hBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23 +KzhmBsUs4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54ugQEC +7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oYNJKiyoOCWTAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUfHJLOcfA22KlT5uqGDSSosqD +glkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3j92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd5 +0XPFtQO3WKwMVC/GVhMPMdoG52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM +7+czV0I664zBechNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws +ZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrIzo9uoV1/A3U0 +5K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATywy39FCqQmbkHzJ8= +-----END CERTIFICATE----- + +Swisscom Root CA 2 +================== +-----BEGIN CERTIFICATE----- +MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBkMQswCQYDVQQG +EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy +dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2 +MjUwNzM4MTRaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln +aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIIC +IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvErjw0DzpPM +LgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r0rk0X2s682Q2zsKwzxNo +ysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJ +wDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVPACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpH +Wrumnf2U5NGKpV+GY3aFy6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1a +SgJA/MTAtukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL6yxS +NLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0uPoTXGiTOmekl9Ab +mbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrALacywlKinh/LTSlDcX3KwFnUey7QY +Ypqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velhk6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3 +qPyZ7iVNTA6z00yPhOgpD/0QVAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw +HQYDVR0hBBYwFDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O +BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqhb97iEoHF8Twu +MA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4RfbgZPnm3qKhyN2abGu2sEzsO +v2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ +82YqZh6NM4OKb3xuqFp1mrjX2lhIREeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLz +o9v/tdhZsnPdTSpxsrpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcs +a0vvaGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciATwoCqISxx +OQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99nBjx8Oto0QuFmtEYE3saW +mA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5Wt6NlUe07qxS/TFED6F+KBZvuim6c779o ++sjaC+NCydAXFJy3SuCvkychVSa1ZC+N8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TC +rvJcwhbtkj6EPnNgiLx29CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX +5OfNeOI5wSsSnqaeG8XmDtkx2Q== +-----END CERTIFICATE----- + +Swisscom Root EV CA 2 +===================== +-----BEGIN CERTIFICATE----- +MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAwZzELMAkGA1UE +BhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdpdGFsIENlcnRpZmljYXRlIFNl +cnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290IEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcN +MzEwNjI1MDg0NTA4WjBnMQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsT +HERpZ2l0YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYg +Q0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7BxUglgRCgz +o3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD1ycfMQ4jFrclyxy0uYAy +Xhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPHoCE2G3pXKSinLr9xJZDzRINpUKTk4Rti +GZQJo/PDvO/0vezbE53PnUgJUmfANykRHvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8Li +qG12W0OfvrSdsyaGOx9/5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaH +Za0zKcQvidm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHLOdAG +alNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaCNYGu+HuB5ur+rPQa +m3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f46Fq9mDU5zXNysRojddxyNMkM3Ox +bPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCBUWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDi +xzgHcgplwLa7JSnaFp6LNYth7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED +MB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWBbj2ITY1x0kbB +bkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6xXCX5145v9Ydkn+0UjrgEjihL +j6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98TPLr+flaYC/NUn81ETm484T4VvwYmneTwkLbU +wp4wLh/vx3rEUMfqe9pQy3omywC0Wqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7 +XwgiG/W9mR4U9s70WBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH +59yLGn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm7JFe3VE/ +23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4Snr8PyQUQ3nqjsTzyP6Wq +J3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VNvBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyA +HmBR3NdUIR7KYndP+tiPsys6DXhyyWhBWkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/gi +uMod89a2GQ+fYWVq6nTIfI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuW +l8PVP3wbI+2ksx0WckNLIOFZfsLorSa/ovc= +-----END CERTIFICATE----- + +CA Disig Root R1 +================ +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNVBAYTAlNLMRMw +EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp +ZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQyMDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sx +EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp +c2lnIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy +3QRkD2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/oOI7bm+V8 +u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3AfQ+lekLZWnDZv6fXARz2 +m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJeIgpFy4QxTaz+29FHuvlglzmxZcfe+5nk +CiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8noc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTa +YVKvJrT1cU/J19IG32PK/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6 +vpmumwKjrckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD3AjL +LhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE7cderVC6xkGbrPAX +ZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkCyC2fg69naQanMVXVz0tv/wQFx1is +XxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLdqvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ +04IwDQYJKoZIhvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR +xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaASfX8MPWbTx9B +LxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXoHqJPYNcHKfyyo6SdbhWSVhlM +CrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpBemOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5Gfb +VSUZP/3oNn6z4eGBrxEWi1CXYBmCAMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85 +YmLLW1AL14FABZyb7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKS +ds+xDzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvkF7mGnjix +lAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqFa3qdnom2piiZk4hA9z7N +UaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsTQ6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJ +a7+h89n07eLw4+1knj0vllJPgFOL +-----END CERTIFICATE----- + +CA Disig Root R2 +================ +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNVBAYTAlNLMRMw +EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp +ZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQyMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sx +EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp +c2lnIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbC +w3OeNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNHPWSb6Wia +xswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3Ix2ymrdMxp7zo5eFm1tL7 +A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbeQTg06ov80egEFGEtQX6sx3dOy1FU+16S +GBsEWmjGycT6txOgmLcRK7fWV8x8nhfRyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqV +g8NTEQxzHQuyRpDRQjrOQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa +5Beny912H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJQfYE +koopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUDi/ZnWejBBhG93c+A +Ak9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORsnLMOPReisjQS1n6yqEm70XooQL6i +Fh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5u +Qu0wDQYJKoZIhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqfGopTpti72TVV +sRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkblvdhuDvEK7Z4bLQjb/D907Je +dR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W8 +1k/BfDxujRNt+3vrMNDcTa/F1balTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjx +mHHEt38OFdAlab0inSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01 +utI3gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18DrG5gPcFw0 +sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3OszMOl6W8KjptlwlCFtaOg +UxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8xL4ysEr3vQCj8KWefshNPZiTEUxnpHikV +7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +ACCVRAIZ1 +========= +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UEAwwJQUNDVlJB +SVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQswCQYDVQQGEwJFUzAeFw0xMTA1 +MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwH +UEtJQUNDVjENMAsGA1UECgwEQUNDVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCbqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gM +jmoYHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWoG2ioPej0 +RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpAlHPrzg5XPAOBOp0KoVdD +aaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhrIA8wKFSVf+DuzgpmndFALW4ir50awQUZ +0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDG +WuzndN9wrqODJerWx5eHk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs7 +8yM2x/474KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMOm3WR +5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpacXpkatcnYGMN285J +9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPluUsXQA+xtrn13k/c4LOsOxFwYIRK +Q26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYIKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRw +Oi8vd3d3LmFjY3YuZXMvZmlsZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEu +Y3J0MB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeTVfZW6oHlNsyM +Hj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIGCCsGAQUFBwICMIIBFB6CARAA +QQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUAcgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBh +AO0AegAgAGQAZQAgAGwAYQAgAEEAQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUA +YwBuAG8AbABvAGcA7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBj +AHQAcgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAAQwBQAFMA +IABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUAczAwBggrBgEFBQcCARYk +aHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2MuaHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0 +dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRtaW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2 +MV9kZXIuY3JsMA4GA1UdDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZI +hvcNAQEFBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdpD70E +R9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gUJyCpZET/LtZ1qmxN +YEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+mAM/EKXMRNt6GGT6d7hmKG9Ww7Y49 +nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepDvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJ +TS+xJlsndQAJxGJ3KQhfnlmstn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3 +sCPdK6jT2iWH7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szAh1xA2syVP1Xg +Nce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xFd3+YJ5oyXSrjhO7FmGYvliAd +3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2HpPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3p +EfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +TWCA Global Root CA +=================== +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcxEjAQBgNVBAoT +CVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMTVFdDQSBHbG9iYWwgUm9vdCBD +QTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQK +EwlUQUlXQU4tQ0ExEDAOBgNVBAsTB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3Qg +Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2C +nJfF10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz0ALfUPZV +r2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfChMBwqoJimFb3u/Rk28OKR +Q4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbHzIh1HrtsBv+baz4X7GGqcXzGHaL3SekV +tTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1W +KKD+u4ZqyPpcC1jcxkt2yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99 +sy2sbZCilaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYPoA/p +yJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQABDzfuBSO6N+pjWxn +kjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcEqYSjMq+u7msXi7Kx/mzhkIyIqJdI +zshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6g +cFGn90xHNcgL1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WFH6vPNOw/KP4M +8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNoRI2T9GRwoD2dKAXDOXC4Ynsg +/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlg +lPx4mI88k1HtQJAH32RjJMtOcQWh15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryP +A9gK8kxkRr05YuWW6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3m +i4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8 +EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3 +zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0= +-----END CERTIFICATE----- + +TeliaSonera Root CA v1 +====================== +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE +CgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4 +MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW +VGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+ +6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA +3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k +B1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn +Xb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH +oLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3 +F0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ +oWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7 +gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc +TwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB +AAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW +DNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm +zqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW +pb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV +G6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc +c41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT +JsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2 +qReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6 +Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems +WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- + +E-Tugra Certification Authority +=============================== +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w +DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls +ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw +NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx +QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl +cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD +DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd +hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K +CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g +ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ +BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0 +E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz +rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq +jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5 +dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB +/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG +MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK +kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO +XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807 +VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo +a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc +dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV +KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT +Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0 +8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G +C7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- + +T-TeleSec GlobalRoot Class 2 +============================ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM +IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU +cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx +MDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz +dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD +ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ +SBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F +vudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970 +2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV +WOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy +YdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4 +r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf +vNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR +3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg== +-----END CERTIFICATE----- + +Atos TrustedRoot 2011 +===================== +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU +cnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4 +MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG +A1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV +hTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr +54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+ +DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320 +HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR +z3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R +l+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ +bNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB +CwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h +k6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh +TZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9 +61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G +3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- + +QuoVadis Root CA 1 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakE +PBtVwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWerNrwU8lm +PNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF34168Xfuw6cwI2H44g4hWf6 +Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh4Pw5qlPafX7PGglTvF0FBM+hSo+LdoIN +ofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXpUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/l +g6AnhF4EwfWQvTA9xO+oabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV +7qJZjqlc3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/GKubX +9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSthfbZxbGL0eUQMk1f +iyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KOTk0k+17kBL5yG6YnLUlamXrXXAkg +t3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOtzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZI +hvcNAQELBQADggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2cDMT/uFPpiN3 +GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUNqXsCHKnQO18LwIE6PWThv6ct +Tr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP ++V04ikkwj+3x6xn0dxoxGE1nVGwvb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh +3jRJjehZrJ3ydlo28hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fa +wx/kNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNjZgKAvQU6 +O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhpq1467HxpvMc7hU6eFbm0 +FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFtnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOV +hMJKzRwuJIczYOXD +-----END CERTIFICATE----- + +QuoVadis Root CA 2 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFh +ZiFfqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMWn4rjyduY +NM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ymc5GQYaYDFCDy54ejiK2t +oIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+o +MiwMzAkd056OXbxMmO7FGmh77FOm6RQ1o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+l +V0POKa2Mq1W/xPtbAd0jIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZo +L1NesNKqIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz8eQQ +sSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43ehvNURG3YBZwjgQQvD +6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l7ZizlWNof/k19N+IxWA1ksB8aRxh +lRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALGcC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZI +hvcNAQELBQADggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RCroijQ1h5fq7K +pVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0GaW/ZZGYjeVYg3UQt4XAoeo0L9 +x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgz +dWqTHBLmYF5vHX/JHyPLhGGfHoJE+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6X +U/IyAgkwo1jwDQHVcsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+Nw +mNtddbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNgKCLjsZWD +zYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeMHVOyToV7BjjHLPj4sHKN +JeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4WSr2Rz0ZiC3oheGe7IUIarFsNMkd7Egr +O3jtZsSOeWmD3n+M +-----END CERTIFICATE----- + +QuoVadis Root CA 3 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286 +IxSR/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNuFoM7pmRL +Mon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXRU7Ox7sWTaYI+FrUoRqHe +6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+cra1AdHkrAj80//ogaX3T7mH1urPnMNA3 +I4ZyYUUpSFlob3emLoG+B01vr87ERRORFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3U +VDmrJqMz6nWB2i3ND0/kA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f7 +5li59wzweyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634RylsSqi +Md5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBpVzgeAVuNVejH38DM +dyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0QA4XN8f+MFrXBsj6IbGB/kE+V9/Yt +rQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZI +hvcNAQELBQADggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnIFUBhynLWcKzS +t/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5WvvoxXqA/4Ti2Tk08HS6IT7SdEQ +TXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFgu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9Du +DcpmvJRPpq3t/O5jrFc/ZSXPsoaP0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGib +Ih6BJpsQBJFxwAYf3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmD +hPbl8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+DhcI00iX +0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HNPlopNLk9hM6xZdRZkZFW +dSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ywaZWWDYWGWVjUTR939+J399roD1B0y2 +PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- + +DigiCert Assured ID Root G2 +=========================== +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw +IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgw +MTE1MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL +ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSAn61UQbVH +35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4HteccbiJVMWWXvdMX0h5i89vq +bFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9HpEgjAALAcKxHad3A2m67OeYfcgnDmCXRw +VWmvo2ifv922ebPynXApVfSr/5Vh88lAbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OP +YLfykqGxvYmJHzDNw6YuYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+Rn +lTGNAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTO +w0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPIQW5pJ6d1Ee88hjZv +0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I0jJmwYrA8y8678Dj1JGG0VDjA9tz +d29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4GnilmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAW +hsI6yLETcDbYz+70CjTVW0z9B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0M +jomZmWzwPDCvON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- + +DigiCert Assured ID Root G3 +=========================== +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD +VQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 +MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQ +BgcqhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJfZn4f5dwb +RXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17QRSAPWXYQ1qAk8C3eNvJs +KTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgF +UaFNN6KDec6NHSrkhDAKBggqhkjOPQQDAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5Fy +YZ5eEJJZVrmDxxDnOOlYJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy +1vUhZscv6pZjamVFkpUBtA== +-----END CERTIFICATE----- + +DigiCert Global Root G2 +======================= +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw +HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUx +MjAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 +dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI2/Ou8jqJ +kTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx1x7e/dfgy5SDN67sH0NO +3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQq2EGnI/yuum06ZIya7XzV+hdG82MHauV +BJVJ8zUtluNJbd134/tJS7SsVQepj5WztCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyM +UNGPHgm+F6HmIcr9g+UQvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQAB +o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV5uNu +5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY1Yl9PMWLSn/pvtsr +F9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4NeF22d+mQrvHRAiGfzZ0JFrabA0U +WTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NGFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBH +QRFXGU7Aj64GxJUTFy8bJZ918rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/ +iyK5S9kJRaTepLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +DigiCert Global Root G3 +======================= +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYD +VQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAw +MDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k +aWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0C +AQYFK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FGfp4tn+6O +YwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPOZ9wj/wMco+I+o0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNp +Yim8S8YwCgYIKoZIzj0EAwMDaAAwZQIxAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y +3maTD/HMsQmP3Wyr+mt/oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34 +VOKa5Vt8sycX +-----END CERTIFICATE----- + +DigiCert Trusted Root G4 +======================== +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw +HwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 +MTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp +pz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9o +k3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7Fsa +vOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY +QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6 +MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtm +mnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7 +f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFH +dL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8 +oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBhjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY +ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdNOj6PWTkiU0Tr +yF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy +7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iah +ixTXTBmyUEFxPT9NcCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN +5r5N0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb +/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP0oUA51Aa +5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tK +G48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP +82Z+ +-----END CERTIFICATE----- + +WoSign +====== +-----BEGIN CERTIFICATE----- +MIIFdjCCA16gAwIBAgIQXmjWEXGUY1BWAGjzPsnFkTANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQG +EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNVBAMTIUNlcnRpZmljYXRpb24g +QXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgwMTAwMDFaMFUxCzAJ +BgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEqMCgGA1UEAxMhQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkgb2YgV29TaWduMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA +vcqNrLiRFVaXe2tcesLea9mhsMMQI/qnobLMMfo+2aYpbxY94Gv4uEBf2zmoAHqLoE1UfcIiePyO +CbiohdfMlZdLdNiefvAA5A6JrkkoRBoQmTIPJYhTpA2zDxIIFgsDcSccf+Hb0v1naMQFXQoOXXDX +2JegvFNBmpGN9J42Znp+VsGQX+axaCA2pIwkLCxHC1l2ZjC1vt7tj/id07sBMOby8w7gLJKA84X5 +KIq0VC6a7fd2/BVoFutKbOsuEo/Uz/4Mx1wdC34FMr5esAkqQtXJTpCzWQ27en7N1QhatH/YHGkR ++ScPewavVIMYe+HdVHpRaG53/Ma/UkpmRqGyZxq7o093oL5d//xWC0Nyd5DKnvnyOfUNqfTq1+ez +EC8wQjchzDBwyYaYD8xYTYO7feUapTeNtqwylwA6Y3EkHp43xP901DfA4v6IRmAR3Qg/UDaruHqk +lWJqbrDKaiFaafPz+x1wOZXzp26mgYmhiMU7ccqjUu6Du/2gd/Tkb+dC221KmYo0SLwX3OSACCK2 +8jHAPwQ+658geda4BmRkAjHXqc1S+4RFaQkAKtxVi8QGRkvASh0JWzko/amrzgD5LkhLJuYwTKVY +yrREgk/nkR4zw7CT/xH8gdLKH3Ep3XZPkiWvHYG3Dy+MwwbMLyejSuQOmbp8HkUff6oZRZb9/D0C +AwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOFmzw7R +8bNLtwYgFP6HEtX2/vs+MA0GCSqGSIb3DQEBBQUAA4ICAQCoy3JAsnbBfnv8rWTjMnvMPLZdRtP1 +LOJwXcgu2AZ9mNELIaCJWSQBnfmvCX0KI4I01fx8cpm5o9dU9OpScA7F9dY74ToJMuYhOZO9sxXq +T2r09Ys/L3yNWC7F4TmgPsc9SnOeQHrAK2GpZ8nzJLmzbVUsWh2eJXLOC62qx1ViC777Y7NhRCOj +y+EaDveaBk3e1CNOIZZbOVtXHS9dCF4Jef98l7VNg64N1uajeeAz0JmWAjCnPv/So0M/BVoG6kQC +2nz4SNAzqfkHx5Xh9T71XXG68pWpdIhhWeO/yloTunK0jF02h+mmxTwTv97QRCbut+wucPrXnbes +5cVAWubXbHssw1abR80LzvobtCHXt2a49CUwi1wNuepnsvRtrtWhnk/Yn+knArAdBtaP4/tIEp9/ +EaEQPkxROpaw0RPxx9gmrjrKkcRpnd8BKWRRb2jaFOwIQZeQjdCygPLPwj2/kWjFgGcexGATVdVh +mVd8upUPYUk6ynW8yQqTP2cOEvIo4jEbwFcW3wh8GcF+Dx+FHgo2fFt+J7x6v+Db9NpSvd4MVHAx +kUOVyLzwPt0JfjBkUO1/AaQzZ01oT74V77D2AhGiGxMlOtzCWfHjXEa7ZywCRuoeSKbmW9m1vFGi +kpbbqsY3Iqb+zCB0oy2pLmvLwIIRIbWTee5Ehr7XHuQe+w== +-----END CERTIFICATE----- + +WoSign China +============ +-----BEGIN CERTIFICATE----- +MIIFWDCCA0CgAwIBAgIQUHBrzdgT/BtOOzNy0hFIjTANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQG +EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMMEkNBIOayg+mAmuagueiv +geS5pjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgwMTAwMDFaMEYxCzAJBgNVBAYTAkNOMRowGAYD +VQQKExFXb1NpZ24gQ0EgTGltaXRlZDEbMBkGA1UEAwwSQ0Eg5rKD6YCa5qC56K+B5LmmMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0EkhHiX8h8EqwqzbdoYGTufQdDTc7WU1/FDWiD+k +8H/rD195L4mx/bxjWDeTmzj4t1up+thxx7S8gJeNbEvxUNUqKaqoGXqW5pWOdO2XCld19AXbbQs5 +uQF/qvbW2mzmBeCkTVL829B0txGMe41P/4eDrv8FAxNXUDf+jJZSEExfv5RxadmWPgxDT74wwJ85 +dE8GRV2j1lY5aAfMh09Qd5Nx2UQIsYo06Yms25tO4dnkUkWMLhQfkWsZHWgpLFbE4h4TV2TwYeO5 +Ed+w4VegG63XX9Gv2ystP9Bojg/qnw+LNVgbExz03jWhCl3W6t8Sb8D7aQdGctyB9gQjF+BNdeFy +b7Ao65vh4YOhn0pdr8yb+gIgthhid5E7o9Vlrdx8kHccREGkSovrlXLp9glk3Kgtn3R46MGiCWOc +76DbT52VqyBPt7D3h1ymoOQ3OMdc4zUPLK2jgKLsLl3Az+2LBcLmc272idX10kaO6m1jGx6KyX2m ++Jzr5dVjhU1zZmkR/sgO9MHHZklTfuQZa/HpelmjbX7FF+Ynxu8b22/8DU0GAbQOXDBGVWCvOGU6 +yke6rCzMRh+yRpY/8+0mBe53oWprfi1tWFxK1I5nuPHa1UaKJ/kR8slC/k7e3x9cxKSGhxYzoacX +GKUN5AXlK8IrC6KVkLn9YDxOiT7nnO4fuwECAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFOBNv9ybQV0T6GTwp+kVpOGBwboxMA0GCSqGSIb3DQEBCwUA +A4ICAQBqinA4WbbaixjIvirTthnVZil6Xc1bL3McJk6jfW+rtylNpumlEYOnOXOvEESS5iVdT2H6 +yAa+Tkvv/vMx/sZ8cApBWNromUuWyXi8mHwCKe0JgOYKOoICKuLJL8hWGSbueBwj/feTZU7n85iY +r83d2Z5AiDEoOqsuC7CsDCT6eiaY8xJhEPRdF/d+4niXVOKM6Cm6jBAyvd0zaziGfjk9DgNyp115 +j0WKWa5bIW4xRtVZjc8VX90xJc/bYNaBRHIpAlf2ltTW/+op2znFuCyKGo3Oy+dCMYYFaA6eFN0A +kLppRQjbbpCBhqcqBT/mhDn4t/lXX0ykeVoQDF7Va/81XwVRHmyjdanPUIPTfPRm94KNPQx96N97 +qA4bLJyuQHCH2u2nFoJavjVsIE4iYdm8UXrNemHcSxH5/mc0zy4EZmFcV5cjjPOGG0jfKq+nwf/Y +jj4Du9gqsPoUJbJRa4ZDhS4HIxaAjUz7tGM7zMN07RujHv41D198HRaG9Q7DlfEvr10lO1Hm13ZB +ONFLAzkopR6RctR9q5czxNM+4Gm2KHmgCY0c0f9BckgG/Jou5yD5m6Leie2uPAmvylezkolwQOQv +T8Jwg0DXJCxr5wkf09XHwQj02w47HAcLQxGEIYbpgNR12KvxAmLBsX5VYc8T1yaw15zLKYs4SgsO +kI26oQ== +-----END CERTIFICATE----- + +COMODO RSA Certification Authority +================================== +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE +BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG +A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwHhcNMTAwMTE5MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMC +R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE +ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0Rn +dJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZ +FGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+ +5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pG +x8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z+pUX +2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQL +OvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3 +sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+C +GCe01a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5 +WdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w +DQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvlwFTPoCWOAvn9sKIN9SCYPBMt +rFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+ +nq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg +tZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW +sRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp +pC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmckejkk9u+UJueBPSZI9FoJA +zMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yLS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHq +ZJx64SIDqZxubw5lT2yHh17zbqD5daWbQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk52 +7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I +LaZRfyHBNVOFBkpdn627G190 +-----END CERTIFICATE----- + +USERTrust RSA Certification Authority +===================================== +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UE +BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK +ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UE +BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK +ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCAEmUXNg7D2wiz +0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2j +Y0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFn +RghRy4YUVD+8M/5+bJz/Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O ++T23LLb2VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq +/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6lZrEpfDKE +Y1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8liM2EuLE/pDkP2QKe6xJM +lXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8 +yexDJtC/QV9AqURE9JnnV4eeUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+ +eLf8ZxXhyVeEHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPFUp/L+M+ZBn8b2kMVn54CVVeW +FPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KOVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ +7l8wXEskEVX/JJpuXior7gtNn3/3ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQ +Eg9zKC7F4iRO/Fjs8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM +8WcRiQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYzeSf7dNXGi +FSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZXHlKYC6SQK5MNyosycdi +yA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9c +J2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRBVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGw +sAvgnEzDHNb842m1R0aBL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gx +Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +USERTrust ECC Certification Authority +===================================== +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC +VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC +VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2 +0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez +nPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV +HQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB +HU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu +9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- + +GlobalSign ECC Root CA - R4 +=========================== +-----BEGIN CERTIFICATE----- +MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprl +OQcJFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAwDgYDVR0P +AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61FuOJAf/sKbvu+M8k8o4TV +MAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGXkPoUVy0D7O48027KqGx2vKLeuwIgJ6iF +JzWbVsaj8kfSt24bAgAXqmemFZHe+pTsewv4n4Q= +-----END CERTIFICATE----- + +GlobalSign ECC Root CA - R5 +=========================== +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6 +SFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS +h5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd +BgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx +uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7 +yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +Staat der Nederlanden Root CA - G3 +================================== +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE +CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g +Um9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloXDTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMC +TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l +ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4y +olQPcPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WWIkYFsO2t +x1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqXxz8ecAgwoNzFs21v0IJy +EavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFyKJLZWyNtZrVtB0LrpjPOktvA9mxjeM3K +Tj215VKb8b475lRgsGYeCasH/lSJEULR9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUur +mkVLoR9BvUhTFXFkC4az5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU5 +1nus6+N86U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7Ngzp +07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHPbMk7ccHViLVlvMDo +FxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXtBznaqB16nzaeErAMZRKQFWDZJkBE +41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTtXUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleu +yjWcLhL75LpdINyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwpLiniyMMB8jPq +KqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8Ipf3YF3qKS9Ysr1YvY2WTxB1 +v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixpgZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA +8KCWAg8zxXHzniN9lLf9OtMJgwYh/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b +8KKaa8MFSu1BYBQw0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0r +mj1AfsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq4BZ+Extq +1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR1VmiiXTTn74eS9fGbbeI +JG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/QFH1T/U67cjF68IeHRaVesd+QnGTbksV +tzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM94B7IWcnMFk= +-----END CERTIFICATE----- + +Staat der Nederlanden EV Root CA +================================ +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJOTDEeMBwGA1UE +CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFhdCBkZXIgTmVkZXJsYW5kZW4g +RVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0yMjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5M +MR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRl +cmxhbmRlbiBFViBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkk +SzrSM4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nCUiY4iKTW +O0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3dZ//BYY1jTw+bbRcwJu+r +0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46prfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8 +Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13lpJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gV +XJrm0w912fxBmJc+qiXbj5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr +08C+eKxCKFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS/ZbV +0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0XcgOPvZuM5l5Tnrmd +74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH1vI4gnPah1vlPNOePqc7nvQDs/nx +fRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrPpx9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwa +ivsnuL8wbqg7MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u2dfOWBfoqSmu +c0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHSv4ilf0X8rLiltTMMgsT7B/Zq +5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTCwPTxGfARKbalGAKb12NMcIxHowNDXLldRqAN +b/9Zjr7dn3LDWyvfjFvO5QxGbJKyCqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tN +f1zuacpzEPuKqf2evTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi +5Dp6Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIaGl6I6lD4 +WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeLeG9QgkRQP2YGiqtDhFZK +DyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGy +eUN51q1veieQA6TqJIc/2b3Z6fJfUEkc7uzXLg== +-----END CERTIFICATE----- + +IdenTrust Commercial Root CA 1 +============================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQG +EwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBS +b290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQwMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzES +MBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB +IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ld +hNlT3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU+ehcCuz/ +mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gpS0l4PJNgiCL8mdo2yMKi +1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1bVoE/c40yiTcdCMbXTMTEl3EASX2MN0C +XZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl +3ZBWzvurpWCdxJ35UrCLvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzy +NeVJSQjKVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZKdHzV +WYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHTc+XvvqDtMwt0viAg +xGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hvl7yTmvmcEpB4eoCHFddydJxVdHix +uuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5NiGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI +hvcNAQELBQADggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwtLRvM7Kqas6pg +ghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt +ozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmV +YjzlVYA211QC//G5Xc7UI2/YRYRKW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUX +feu+h1sXIFRRk0pTAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/ro +kTLql1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG4iZZRHUe +2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZmUlO+KWA2yUPHGNiiskz +Z2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7R +cGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +IdenTrust Public Sector Root CA 1 +================================= +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG +EwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3Rv +ciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcNMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJV +UzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBS +b290IENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTy +P4o7ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGyRBb06tD6 +Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlSbdsHyo+1W/CD80/HLaXI +rcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF/YTLNiCBWS2ab21ISGHKTN9T0a9SvESf +qy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoS +mJxZZoY+rfGwyj4GD3vwEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFn +ol57plzy9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9VGxyh +LrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ2fjXctscvG29ZV/v +iDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsVWaFHVCkugyhfHMKiq3IXAAaOReyL +4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gDW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8B +Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMw +DQYJKoZIhvcNAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHVDRDtfULAj+7A +mgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9TaDKQGXSc3z1i9kKlT/YPyNt +GtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8GlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFt +m6/n6J91eEyrRjuazr8FGF1NFTwWmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMx +NRF4eKLg6TCMf4DfWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4 +Mhn5+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJtshquDDI +ajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhAGaQdp/lLQzfcaFpPz+vC +ZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ +3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +Entrust Root Certification Authority - G2 +========================================= +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV +BAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy +bXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug +b25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw +HhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT +DUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx +OTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP +/vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz +HHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU +s/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y +TGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx +AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6 +0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z +iXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi +nWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+ +vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO +e4pIb4tF9g== +-----END CERTIFICATE----- + +Entrust Root Certification Authority - EC1 +========================================== +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx +FjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn +YWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl +ZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw +FAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs +LXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg +dXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt +IEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy +AsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef +9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h +vxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8 +kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- + +CFCA EV ROOT +============ +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDTjEwMC4GA1UE +CgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB +IEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw +MC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQD +DAxDRkNBIEVWIFJPT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnV +BU03sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpLTIpTUnrD +7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5/ZOkVIBMUtRSqy5J35DN +uF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp7hZZLDRJGqgG16iI0gNyejLi6mhNbiyW +ZXvKWfry4t3uMCz7zEasxGPrb382KzRzEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7 +xzbh72fROdOXW3NiGUgthxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9f +py25IGvPa931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqotaK8K +gWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNgTnYGmE69g60dWIol +hdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfVPKPtl8MeNPo4+QgO48BdK4PRVmrJ +tqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hvcWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAf +BgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB +/wQEAwIBBjAdBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObTej/tUxPQ4i9q +ecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdLjOztUmCypAbqTuv0axn96/Ua +4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBSESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sG +E5uPhnEFtC+NiWYzKXZUmhH4J/qyP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfX +BDrDMlI1Dlb4pd19xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjn +aH9dCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN5mydLIhy +PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX +kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C +ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5 +==================================================== +-----BEGIN CERTIFICATE----- +MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UEBhMCVFIxDzAN +BgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp +bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1Qg +RWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAw +ODA3MDFaFw0yMzA0MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0w +SwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnE +n2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRp +ZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEApCUZ4WWe60ghUEoI5RHwWrom/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537 +jVJp45wnEFPzpALFp/kRGml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1m +ep5Fimh34khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z5UNP +9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0hO8EuPbJbKoCPrZV +4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QIDAQABo0IwQDAdBgNVHQ4EFgQUVpkH +HtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI +hvcNAQELBQADggEBAJ5FdnsXSDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPo +BP5yCccLqh0lVX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq +URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nfpeYVhDfwwvJl +lpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CFYv4HAqGEVka+lgqaE9chTLd8 +B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW+qtB4Uu2NQvAmxU= +-----END CERTIFICATE----- + +TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6 +==================================================== +-----BEGIN CERTIFICATE----- +MIIEJjCCAw6gAwIBAgIGfaHyZeyKMA0GCSqGSIb3DQEBCwUAMIGxMQswCQYDVQQGEwJUUjEPMA0G +A1UEBwwGQW5rYXJhMU0wSwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls +acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg2MB4XDTEzMTIxODA5 +MDQxMFoXDTIzMTIxNjA5MDQxMFowgbExCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExTTBL +BgNVBAoMRFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2ZW5sacSf +aSBIaXptZXRsZXJpIEEuxZ4uMUIwQAYDVQQDDDlUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2VydGlm +aWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLEgSDYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCdsGjW6L0UlqMACprx9MfMkU1xeHe59yEmFXNRFpQJRwXiM/VomjX/3EsvMsew7eKC5W/a +2uqsxgbPJQ1BgfbBOCK9+bGlprMBvD9QFyv26WZV1DOzXPhDIHiTVRZwGTLmiddk671IUP320EED +wnS3/faAz1vFq6TWlRKb55cTMgPp1KtDWxbtMyJkKbbSk60vbNg9tvYdDjTu0n2pVQ8g9P0pu5Fb +HH3GQjhtQiht1AH7zYiXSX6484P4tZgvsycLSF5W506jM7NE1qXyGJTtHB6plVxiSvgNZ1GpryHV ++DKdeboaX+UEVU0TRv/yz3THGmNtwx8XEsMeED5gCLMxAgMBAAGjQjBAMB0GA1UdDgQWBBTdVRcT +9qzoSCHK77Wv0QAy7Z6MtTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG +9w0BAQsFAAOCAQEAb1gNl0OqFlQ+v6nfkkU/hQu7VtMMUszIv3ZnXuaqs6fvuay0EBQNdH49ba3R +fdCaqaXKGDsCQC4qnFAUi/5XfldcEQlLNkVS9z2sFP1E34uXI9TDwe7UU5X+LEr+DXCqu4svLcsy +o4LyVN/Y8t3XSHLuSqMplsNEzm61kod2pLv0kmzOLBQJZo6NrRa1xxsJYTvjIKIDgI6tflEATseW +hvtDmHd9KMeP2Cpu54Rvl0EpABZeTeIT6lnAY2c6RPuY/ATTMHKm9ocJV612ph1jmv3XZch4gyt1 +O6VbuA1df74jrlZVlFjvH4GMKrLN5ptjnhi85WsGtAuYSyher4hYyw== +-----END CERTIFICATE----- + +Certinomis - Root CA +==================== +-----BEGIN CERTIFICATE----- +MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjETMBEGA1UEChMK +Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAbBgNVBAMTFENlcnRpbm9taXMg +LSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMzMTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIx +EzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRD +ZXJ0aW5vbWlzIC0gUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQos +P5L2fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJflLieY6pOo +d5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQVWZUKxkd8aRi5pwP5ynap +z8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDFTKWrteoB4owuZH9kb/2jJZOLyKIOSY00 +8B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09x +RLWtwHkziOC/7aOgFLScCbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE +6OXWk6RiwsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJwx3t +FvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SGm/lg0h9tkQPTYKbV +PZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4F2iw4lNVYC2vPsKD2NkJK/DAZNuH +i5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZngWVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGj +YzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I +6tNxIqSSaHh02TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF +AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/0KGRHCwPT5iV +WVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWwF6YSjNRieOpWauwK0kDDPAUw +Pk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZSg081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAX +lCOotQqSD7J6wWAsOMwaplv/8gzjqh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJ +y29SWwNyhlCVCNSNh4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9 +Iff/ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8Vbtaw5Bng +DwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwjY/M50n92Uaf0yKHxDHYi +I0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nM +cyrDflOR1m749fPH0FFNjkulW+YZFzvWgQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVr +hkIGuUE= +-----END CERTIFICATE----- + +OISTE WISeKey Global Root GB CA +=============================== +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG +EwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl +ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw +MzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD +VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds +b2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX +scriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP +rby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk +9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o +Qnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg +GUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI +hvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD +dHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0 +VQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui +HZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +Certification Authority of WoSign G2 +==================================== +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQayXaioidfLwPBbOxemFFRDANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQG +EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxLTArBgNVBAMTJENlcnRpZmljYXRpb24g +QXV0aG9yaXR5IG9mIFdvU2lnbiBHMjAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4NThaMFgx +CzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEtMCsGA1UEAxMkQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkgb2YgV29TaWduIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAvsXEoCKASU+/2YcRxlPhuw+9YH+v9oIOH9ywjj2X4FA8jzrvZjtFB5sg+OPXJYY1kBai +XW8wGQiHC38Gsp1ij96vkqVg1CuAmlI/9ZqD6TRay9nVYlzmDuDfBpgOgHzKtB0TiGsOqCR3A9Du +W/PKaZE1OVbFbeP3PU9ekzgkyhjpJMuSA93MHD0JcOQg5PGurLtzaaNjOg9FD6FKmsLRY6zLEPg9 +5k4ot+vElbGs/V6r+kHLXZ1L3PR8du9nfwB6jdKgGlxNIuG12t12s9R23164i5jIFFTMaxeSt+BK +v0mUYQs4kI9dJGwlezt52eJ+na2fmKEG/HgUYFf47oB3sQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU+mCp62XF3RYUCE4MD42b4Pdkr2cwDQYJKoZI +hvcNAQELBQADggEBAFfDejaCnI2Y4qtAqkePx6db7XznPWZaOzG73/MWM5H8fHulwqZm46qwtyeY +P0nXYGdnPzZPSsvxFPpahygc7Y9BMsaV+X3avXtbwrAh449G3CE4Q3RM+zD4F3LBMvzIkRfEzFg3 +TgvMWvchNSiDbGAtROtSjFA9tWwS1/oJu2yySrHFieT801LYYRf+epSEj3m2M1m6D8QL4nCgS3gu ++sif/a+RZQp4OBXllxcU3fngLDT4ONCEIgDAFFEYKwLcMFrw6AF8NTojrwjkr6qOKEJJLvD1mTS+ +7Q9LGOHSJDy7XUe3IfKN0QqZjuNuPq1w4I+5ysxugTH2e5x6eeRncRg= +-----END CERTIFICATE----- + +CA WoSign ECC Root +================== +-----BEGIN CERTIFICATE----- +MIICCTCCAY+gAwIBAgIQaEpYcIBr8I8C+vbe6LCQkDAKBggqhkjOPQQDAzBGMQswCQYDVQQGEwJD +TjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMTEkNBIFdvU2lnbiBFQ0MgUm9v +dDAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4NThaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQK +ExFXb1NpZ24gQ0EgTGltaXRlZDEbMBkGA1UEAxMSQ0EgV29TaWduIEVDQyBSb290MHYwEAYHKoZI +zj0CAQYFK4EEACIDYgAE4f2OuEMkq5Z7hcK6C62N4DrjJLnSsb6IOsq/Srj57ywvr1FQPEd1bPiU +t5v8KB7FVMxjnRZLU8HnIKvNrCXSf4/CwVqCXjCLelTOA7WRf6qU0NGKSMyCBSah1VES1ns2o0Iw +QDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUqv3VWqP2h4syhf3R +MluARZPzA7gwCgYIKoZIzj0EAwMDaAAwZQIxAOSkhLCB1T2wdKyUpOgOPQB0TKGXa/kNUTyh2Tv0 +Daupn75OcsqF1NnstTJFGG+rrQIwfcf3aWMvoeGY7xMQ0Xk/0f7qO3/eVvSQsRUR2LIiFdAvwyYu +a/GRspBl9JrmkO5K +-----END CERTIFICATE----- + +SZAFIR ROOT CA2 +=============== +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG +A1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV +BAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ +BgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD +VQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q +qEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK +DJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE +2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ +ckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi +ieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC +AQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5 +O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67 +oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul +4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6 ++/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +Certum Trusted Network CA 2 +=========================== +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE +BhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1 +bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y +ayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ +TDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB +IDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9 +7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o +CgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b +Rr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p +uTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130 +GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ +9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB +Rgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye +hizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM +BhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI +hvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW +Al45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA +L55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo +clm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM +pkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb +w3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo +J/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm +ypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX +is7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7 +zAYspsbiDrW5viSP +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions RootCA 2015 +======================================================= +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcT +BkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0 +aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl +YXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAx +MTIxWjCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMg +QWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNV +BAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIw +MTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDC+Kk/G4n8PDwEXT2QNrCROnk8Zlrv +bTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+eh +iGsxr/CL0BgzuNtFajT0AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+ +6PAQZe104S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06CojXd +FPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV9Cz82XBST3i4vTwr +i5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrDgfgXy5I2XdGj2HUb4Ysn6npIQf1F +GQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2 +fu/Z8VFRfS0myGlZYeCsargqNhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9mu +iNX6hME6wGkoLfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVdctA4GGqd83EkVAswDQYJKoZI +hvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0IXtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+ +D1hYc2Ryx+hFjtyp8iY/xnmMsVMIM4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrM +d/K4kPFox/la/vot9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+y +d+2VZ5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/eaj8GsGsVn +82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnhX9izjFk0WaSrT2y7Hxjb +davYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQl033DlZdwJVqwjbDG2jJ9SrcR5q+ss7F +Jej6A7na+RZukYT1HCjI/CbM1xyQVqdfbzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVt +J94Cj8rDtSvK6evIIVM4pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGa +JI7ZjnHKe7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0vm9q +p/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions ECC RootCA 2015 +=========================================================== +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0 +aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u +cyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj +aCBJbnN0aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEw +MzcxMlowgaoxCzAJBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmlj +IEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUQwQgYD +VQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIEVDQyBSb290 +Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKgQehLgoRc4vgxEZmGZE4JJS+dQS8KrjVP +dJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJajq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoK +Vlp8aQuqgAkkbH7BRqNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O +BBYEFLQiC4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaeplSTA +GiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7SofTUwJCA3sS61kFyjn +dc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +Certplus Root CA G1 +=================== +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgISESBVg+QtPlRWhS2DN7cs3EYRMA0GCSqGSIb3DQEBDQUAMD4xCzAJBgNV +BAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTAe +Fw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhD +ZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBANpQh7bauKk+nWT6VjOaVj0W5QOVsjQcmm1iBdTYj+eJZJ+622SLZOZ5KmHN +r49aiZFluVj8tANfkT8tEBXgfs+8/H9DZ6itXjYj2JizTfNDnjl8KvzsiNWI7nC9hRYt6kuJPKNx +Qv4c/dMcLRC4hlTqQ7jbxofaqK6AJc96Jh2qkbBIb6613p7Y1/oA/caP0FG7Yn2ksYyy/yARujVj +BYZHYEMzkPZHogNPlk2dT8Hq6pyi/jQu3rfKG3akt62f6ajUeD94/vI4CTYd0hYCyOwqaK/1jpTv +LRN6HkJKHRUxrgwEV/xhc/MxVoYxgKDEEW4wduOU8F8ExKyHcomYxZ3MVwia9Az8fXoFOvpHgDm2 +z4QTd28n6v+WZxcIbekN1iNQMLAVdBM+5S//Ds3EC0pd8NgAM0lm66EYfFkuPSi5YXHLtaW6uOrc +4nBvCGrch2c0798wct3zyT8j/zXhviEpIDCB5BmlIOklynMxdCm+4kLV87ImZsdo/Rmz5yCTmehd +4F6H50boJZwKKSTUzViGUkAksnsPmBIgJPaQbEfIDbsYIC7Z/fyL8inqh3SV4EJQeIQEQWGw9CEj +jy3LKCHyamz0GqbFFLQ3ZU+V/YDI+HLlJWvEYLF7bY5KinPOWftwenMGE9nTdDckQQoRb5fc5+R+ +ob0V8rqHDz1oihYHAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0G +A1UdDgQWBBSowcCbkahDFXxdBie0KlHYlwuBsTAfBgNVHSMEGDAWgBSowcCbkahDFXxdBie0KlHY +lwuBsTANBgkqhkiG9w0BAQ0FAAOCAgEAnFZvAX7RvUz1isbwJh/k4DgYzDLDKTudQSk0YcbX8ACh +66Ryj5QXvBMsdbRX7gp8CXrc1cqh0DQT+Hern+X+2B50ioUHj3/MeXrKls3N/U/7/SMNkPX0XtPG +YX2eEeAC7gkE2Qfdpoq3DIMku4NQkv5gdRE+2J2winq14J2by5BSS7CTKtQ+FjPlnsZlFT5kOwQ/ +2wyPX1wdaR+v8+khjPPvl/aatxm2hHSco1S1cE5j2FddUyGbQJJD+tZ3VTNPZNX70Cxqjm0lpu+F +6ALEUz65noe8zDUa3qHpimOHZR4RKttjd5cUvpoUmRGywO6wT/gUITJDT5+rosuoD6o7BlXGEilX +CNQ314cnrUlZp5GrRHpejXDbl85IULFzk/bwg2D5zfHhMf1bfHEhYxQUqq/F3pN+aLHsIqKqkHWe +tUNy6mSjhEv9DKgma3GX7lZjZuhCVPnHHd/Qj1vfyDBviP4NxDMcU6ij/UgQ8uQKTuEVV/xuZDDC +VRHc6qnNSlSsKWNEz0pAoNZoWRsz+e86i9sgktxChL8Bq4fA1SCC28a5g4VCXA9DO2pJNdWY9BW/ ++mGBDAkgGNLQFwzLSABQ6XaCjGTXOqAHVcweMcDvOrRl++O/QmueD6i9a5jc2NvLi6Td11n0bt3+ +qsOR0C5CB8AMTVPNJLFMWx5R9N/pkvo= +-----END CERTIFICATE----- + +Certplus Root CA G2 +=================== +-----BEGIN CERTIFICATE----- +MIICHDCCAaKgAwIBAgISESDZkc6uo+jF5//pAq/Pc7xVMAoGCCqGSM49BAMDMD4xCzAJBgNVBAYT +AkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjAeFw0x +NDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0 +cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjB2MBAGByqGSM49AgEGBSuBBAAiA2IA +BM0PW1aC3/BFGtat93nwHcmsltaeTpwftEIRyoa/bfuFo8XlGVzX7qY/aWfYeOKmycTbLXku54uN +Am8xIk0G42ByRZ0OQneezs/lf4WbGOT8zC5y0xaTTsqZY1yhBSpsBqNjMGEwDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMB8GA1Ud +IwQYMBaAFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMAoGCCqGSM49BAMDA2gAMGUCMHD+sAvZ94OX7PNV +HdTcswYO/jOYnYs5kGuUIe22113WTNchp+e/IQ8rzfcq3IUHnQIxAIYUFuXcsGXCwI4Un78kFmjl +vPl5adytRSv3tjFzzAalU5ORGpOucGpnutee5WEaXw== +-----END CERTIFICATE----- + +OpenTrust Root CA G1 +==================== +-----BEGIN CERTIFICATE----- +MIIFbzCCA1egAwIBAgISESCzkFU5fX82bWTCp59rY45nMA0GCSqGSIb3DQEBCwUAMEAxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcx +MB4XDTE0MDUyNjA4NDU1MFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM +CU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzEwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQD4eUbalsUwXopxAy1wpLuwxQjczeY1wICkES3d5oeuXT2R0odsN7fa +Yp6bwiTXj/HbpqbfRm9RpnHLPhsxZ2L3EVs0J9V5ToybWL0iEA1cJwzdMOWo010hOHQX/uMftk87 +ay3bfWAfjH1MBcLrARYVmBSO0ZB3Ij/swjm4eTrwSSTilZHcYTSSjFR077F9jAHiOH3BX2pfJLKO +YheteSCtqx234LSWSE9mQxAGFiQD4eCcjsZGT44ameGPuY4zbGneWK2gDqdkVBFpRGZPTBKnjix9 +xNRbxQA0MMHZmf4yzgeEtE7NCv82TWLxp2NX5Ntqp66/K7nJ5rInieV+mhxNaMbBGN4zK1FGSxyO +9z0M+Yo0FMT7MzUj8czxKselu7Cizv5Ta01BG2Yospb6p64KTrk5M0ScdMGTHPjgniQlQ/GbI4Kq +3ywgsNw2TgOzfALU5nsaqocTvz6hdLubDuHAk5/XpGbKuxs74zD0M1mKB3IDVedzagMxbm+WG+Oi +n6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPwvFEVVJSmdz7QdFG9 +URQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYYEQRVzXR7z2FwefR7LFxckvzluFqr +TJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUl0YhVyE12jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/Px +N3DlCPaTKbYwDQYJKoZIhvcNAQELBQADggIBAB3dAmB84DWn5ph76kTOZ0BP8pNuZtQ5iSas000E +PLuHIT839HEl2ku6q5aCgZG27dmxpGWX4m9kWaSW7mDKHyP7Rbr/jyTwyqkxf3kfgLMtMrpkZ2Cv +uVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbSFXJfLkur1J1juONI5f6ELlgK +n0Md/rcYkoZDSw6cMoYsYPXpSOqV7XAp8dUv/TW0V8/bhUiZucJvbI/NeJWsZCj9VrDDb8O+WVLh +X4SPgPL0DTatdrOjteFkdjpY3H1PXlZs5VVZV6Xf8YpmMIzUUmI4d7S+KNfKNsSbBfD4Fdvb8e80 +nR14SohWZ25g/4/Ii+GOvUKpMwpZQhISKvqxnUOOBZuZ2mKtVzazHbYNeS2WuOvyDEsMpZTGMKcm +GS3tTAZQMPH9WD25SxdfGbRqhFS0OE85og2WaMMolP3tLR9Ka0OWLpABEPs4poEL0L9109S5zvE/ +bw4cHjdx5RiHdRk/ULlepEU0rbDK5uUTdg8xFKmOLZTW1YVNcxVPS/KyPu1svf0OnWZzsD2097+o +4BGkxK51CUpjAEggpsadCwmKtODmzj7HPiY46SvepghJAwSQiumPv+i2tCqjI40cHLI5kqiPAlxA +OXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj1oxx +-----END CERTIFICATE----- + +OpenTrust Root CA G2 +==================== +-----BEGIN CERTIFICATE----- +MIIFbzCCA1egAwIBAgISESChaRu/vbm9UpaPI+hIvyYRMA0GCSqGSIb3DQEBDQUAMEAxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcy +MB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM +CU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzIwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDMtlelM5QQgTJT32F+D3Y5z1zCU3UdSXqWON2ic2rxb95eolq5cSG+ +Ntmh/LzubKh8NBpxGuga2F8ORAbtp+Dz0mEL4DKiltE48MLaARf85KxP6O6JHnSrT78eCbY2albz +4e6WiWYkBuTNQjpK3eCasMSCRbP+yatcfD7J6xcvDH1urqWPyKwlCm/61UWY0jUJ9gNDlP7ZvyCV +eYCYitmJNbtRG6Q3ffyZO6v/v6wNj0OxmXsWEH4db0fEFY8ElggGQgT4hNYdvJGmQr5J1WqIP7wt +UdGejeBSzFfdNTVY27SPJIjki9/ca1TSgSuyzpJLHB9G+h3Ykst2Z7UJmQnlrBcUVXDGPKBWCgOz +3GIZ38i1MH/1PCZ1Eb3XG7OHngevZXHloM8apwkQHZOJZlvoPGIytbU6bumFAYueQ4xncyhZW+vj +3CzMpSZyYhK05pyDRPZRpOLAeiRXyg6lPzq1O4vldu5w5pLeFlwoW5cZJ5L+epJUzpM5ChaHvGOz +9bGTXOBut9Dq+WIyiET7vycotjCVXRIouZW+j1MY5aIYFuJWpLIsEPUdN6b4t/bQWVyJ98LVtZR0 +0dX+G7bw5tYee9I8y6jj9RjzIR9u701oBnstXW5DiabA+aC/gh7PU3+06yzbXfZqfUAkBXKJOAGT +y3HCOV0GEfZvePg3DTmEJwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUajn6QiL35okATV59M4PLuG53hq8wHwYDVR0jBBgwFoAUajn6QiL35okATV59 +M4PLuG53hq8wDQYJKoZIhvcNAQENBQADggIBAJjLq0A85TMCl38th6aP1F5Kr7ge57tx+4BkJamz +Gj5oXScmp7oq4fBXgwpkTx4idBvpkF/wrM//T2h6OKQQbA2xx6R3gBi2oihEdqc0nXGEL8pZ0keI +mUEiyTCYYW49qKgFbdEfwFFEVn8nNQLdXpgKQuswv42hm1GqO+qTRmTFAHneIWv2V6CG1wZy7HBG +S4tz3aAhdT7cHcCP009zHIXZ/n9iyJVvttN7jLpTwm+bREx50B1ws9efAvSyB7DH5fitIw6mVskp +EndI2S9G/Tvw/HRwkqWOOAgfZDC2t0v7NqwQjqBSM2OdAzVWxWm9xiNaJ5T2pBL4LTM8oValX9YZ +6e18CL13zSdkzJTaTkZQh+D5wVOAHrut+0dSixv9ovneDiK3PTNZbNTe9ZUGMg1RGUFcPk8G97kr +gCf2o6p6fAbhQ8MTOWIaNr3gKC6UAuQpLmBVrkA9sHSSXvAgZJY/X0VdiLWK2gKgW0VU3jg9CcCo +SmVGFvyqv1ROTVu+OEO3KMqLM6oaJbolXCkvW0pujOotnCr2BXbgd5eAiN1nE28daCSLT7d0geX0 +YJ96Vdc+N9oWaz53rK4YcJUIeSkDiv7BO7M/Gg+kO14fWKGVyasvc0rQLW6aWQ9VGHgtPFGml4vm +u7JwqkwR3v98KzfUetF3NI/n+UL3PIEMS1IK +-----END CERTIFICATE----- + +OpenTrust Root CA G3 +==================== +-----BEGIN CERTIFICATE----- +MIICITCCAaagAwIBAgISESDm+Ez8JLC+BUCs2oMbNGA/MAoGCCqGSM49BAMDMEAxCzAJBgNVBAYT +AkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEczMB4X +DTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9w +ZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzMwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAARK7liuTcpm3gY6oxH84Bjwbhy6LTAMidnW7ptzg6kjFYwvWYpa3RTqnVkrQ7cG7DK2uu5B +ta1doYXM6h0UZqNnfkbilPPntlahFVmhTzeXuSIevRHr9LIfXsMUmuXZl5mjYzBhMA4GA1UdDwEB +/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAf +BgNVHSMEGDAWgBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAKBggqhkjOPQQDAwNpADBmAjEAj6jcnboM +BBf6Fek9LykBl7+BFjNAk2z8+e2AcG+qj9uEwov1NcoG3GRvaBbhj5G5AjEA2Euly8LQCGzpGPta +3U1fJAuwACEl74+nBCZx4nxp5V2a+EEfOzmTk51V6s2N8fvB +-----END CERTIFICATE----- + +ISRG Root X1 +============ +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UE +BhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNoIEdyb3VwMRUwEwYDVQQD +EwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQG +EwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMT +DElTUkcgUm9vdCBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54r +Vygch77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+0TM8ukj1 +3Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6UA5/TR5d8mUgjU+g4rk8K +b4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sWT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCN +Aymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyHB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ +4Q7e2RCOFvu396j3x+UCB5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf +1b0SHzUvKBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWnOlFu +hjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTnjh8BCNAw1FtxNrQH +usEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbwqHyGO0aoSCqI3Haadr8faqU9GY/r +OPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CIrU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4G +A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY +9umbbjANBgkqhkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ3BebYhtF8GaV +0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KKNFtY2PwByVS5uCbMiogziUwt +hDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJw +TdwJx4nLCgdNbOhdjsnvzqvHu7UrTkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nx +e5AW0wdeRlN8NwdCjNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZA +JzVcoyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq4RgqsahD +YVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPAmRGunUHBcnWEvgJBQl9n +JEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57demyPxgcYxn/eR44/KJ4EBs+lVDR3veyJ +m+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- + +AC RAIZ FNMT-RCM +================ +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNVBAYT +AkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTAeFw0wODEw +MjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJD +TTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBALpxgHpMhm5/yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcf +qQgfBBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAzWHFctPVr +btQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxFtBDXaEAUwED653cXeuYL +j2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z374jNUUeAlz+taibmSXaXvMiwzn15Cou +08YfxGyqxRxqAQVKL9LFwag0Jl1mpdICIfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mw +WsXmo8RZZUc1g16p6DULmbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnT +tOmlcYF7wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peSMKGJ +47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2ZSysV4999AeU14EC +ll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMetUqIJ5G+GR4of6ygnXYMgrwTJbFaa +i0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FPd9xf3E6Jobd2Sn9R2gzL+HYJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1o +dHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1RXxlDPiyN8+s +D8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYMLVN0V2Ue1bLdI4E7pWYjJ2cJ +j+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrT +Qfv6MooqtyuGC2mDOL7Nii4LcK2NJpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW ++YJF1DngoABd15jmfZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7 +Ixjp6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp1txyM/1d +8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B9kiABdcPUXmsEKvU7ANm +5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wokRqEIr9baRRmW1FMdW4R58MD3R++Lj8UG +rp1MYp3/RgT408m2ECVAdf4WqslKYIYvuu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- + +Amazon Root CA 1 +================ +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD +VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1 +MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv +bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH +FzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ +gLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t +dHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce +VOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3 +DQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM +CCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy +8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa +2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2 +xJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- + +Amazon Root CA 2 +================ +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD +VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1 +MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv +bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4 +kHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp +N+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9 +AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd +fLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx +kv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS +btqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0 +Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN +c/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf+ +3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw +DPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA +A7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE +YFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW +xkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ +gj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW +aQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV +Yh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3 +KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi +JUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw= +-----END CERTIFICATE----- + +Amazon Root CA 3 +================ +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG +EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy +NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ +MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB +f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr +Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43 +rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc +eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw== +-----END CERTIFICATE----- + +Amazon Root CA 4 +================ +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG +EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy +NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ +MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN +/sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri +83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA +MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1 +AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- + +LuxTrust Global Root 2 +====================== +-----BEGIN CERTIFICATE----- +MIIFwzCCA6ugAwIBAgIUCn6m30tEntpqJIWe5rgV0xZ/u7EwDQYJKoZIhvcNAQELBQAwRjELMAkG +A1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNVBAMMFkx1eFRydXN0IEdsb2Jh +bCBSb290IDIwHhcNMTUwMzA1MTMyMTU3WhcNMzUwMzA1MTMyMTU3WjBGMQswCQYDVQQGEwJMVTEW +MBQGA1UECgwNTHV4VHJ1c3QgUy5BLjEfMB0GA1UEAwwWTHV4VHJ1c3QgR2xvYmFsIFJvb3QgMjCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANeFl78RmOnwYoNMPIf5U2o3C/IPPIfOb9wm +Kb3FibrJgz337spbxm1Jc7TJRqMbNBM/wYlFV/TZsfs2ZUv7COJIcRHIbjuend+JZTemhfY7RBi2 +xjcwYkSSl2l9QjAk5A0MiWtj3sXh306pFGxT4GHO9hcvHTy95iJMHZP1EMShduxq3sVs35a0VkBC +wGKSMKEtFZSg0iAGCW5qbeXrt77U8PEVfIvmTroTzEsnXpk8F12PgX8zPU/TPxvsXD/wPEx1bvKm +1Z3aLQdjAsZy6ZS8TEmVT4hSyNvoaYL4zDRbIvCGp4m9SAptZoFtyMhk+wHh9OHe2Z7d21vUKpkm +FRseTJIpgp7VkoGSQXAZ96Tlk0u8d2cx3Rz9MXANF5kM+Qw5GSoXtTBxVdUPrljhPS80m8+f9niF +wpN6cj5mj5wWEWCPnolvZ77gR1o7DJpni89Gxq44o/KnvObWhWszJHAiS8sIm7vI+AIpHb4gDEa/ +a4ebsypmQjVGbKq6rfmYe+lQVRQxv7HaLe2ArWgk+2mr2HETMOZns4dA/Yl+8kPREd8vZS9kzl8U +ubG/Mb2HeFpZZYiq/FkySIbWTLkpS5XTdvN3JW1CHDiDTf2jX5t/Lax5Gw5CMZdjpPuKadUiDTSQ +MC6otOBttpSsvItO13D8xTiOZCXhTTmQzsmHhFhxAgMBAAGjgagwgaUwDwYDVR0TAQH/BAUwAwEB +/zBCBgNVHSAEOzA5MDcGByuBKwEBAQowLDAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBvc2l0b3J5 +Lmx1eHRydXN0Lmx1MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBT/GCh2+UgFLKGu8SsbK7JT ++Et8szAdBgNVHQ4EFgQU/xgodvlIBSyhrvErGyuyU/hLfLMwDQYJKoZIhvcNAQELBQADggIBAGoZ +FO1uecEsh9QNcH7X9njJCwROxLHOk3D+sFTAMs2ZMGQXvw/l4jP9BzZAcg4atmpZ1gDlaCDdLnIN +H2pkMSCEfUmmWjfrRcmF9dTHF5kH5ptV5AzoqbTOjFu1EVzPig4N1qx3gf4ynCSecs5U89BvolbW +7MM3LGVYvlcAGvI1+ut7MV3CwRI9loGIlonBWVx65n9wNOeD4rHh4bhY79SV5GCc8JaXcozrhAIu +ZY+kt9J/Z93I055cqqmkoCUUBpvsT34tC38ddfEz2O3OuHVtPlu5mB0xDVbYQw8wkbIEa91WvpWA +VWe+2M2D2RjuLg+GLZKecBPs3lHJQ3gCpU3I+V/EkVhGFndadKpAvAefMLmx9xIX3eP/JEAdemrR +TxgKqpAd60Ae36EeRJIQmvKN4dFLRp7oRUKX6kWZ8+xm1QL68qZKJKrezrnK+T+Tb/mjuuqlPpmt +/f97mfVl7vBZKGfXkJWkE4SphMHozs51k2MavDzq1WQfLSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc +7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31I +iyBMz2TWuJdGsE7RKlY6oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr +-----END CERTIFICATE----- diff --git a/Gems/AWSCore/Code/CMakeLists.txt b/Gems/AWSCore/Code/CMakeLists.txt index e6da67d2b3..4b12dde831 100644 --- a/Gems/AWSCore/Code/CMakeLists.txt +++ b/Gems/AWSCore/Code/CMakeLists.txt @@ -6,12 +6,14 @@ # ly_get_list_relative_pal_filename(pal_editor_include_dir ${CMAKE_CURRENT_LIST_DIR}/Include/Private/Editor/Platform/${PAL_PLATFORM_NAME}) +ly_get_list_relative_pal_filename(pal_cafile_include_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Framework/Platform/${PAL_PLATFORM_NAME}) ly_add_target( NAME AWSCore.Static STATIC NAMESPACE Gem FILES_CMAKE awscore_files.cmake + ${pal_cafile_include_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake INCLUDE_DIRECTORIES PUBLIC Include/Public diff --git a/Gems/AWSCore/Code/Source/Framework/AWSApiJob.cpp b/Gems/AWSCore/Code/Source/Framework/AWSApiJob.cpp index 8800094b95..4383e0a8ac 100644 --- a/Gems/AWSCore/Code/Source/Framework/AWSApiJob.cpp +++ b/Gems/AWSCore/Code/Source/Framework/AWSApiJob.cpp @@ -9,6 +9,10 @@ namespace AWSCore { + namespace Platform + { + Aws::String GetCaCertBundlePath(); + } const char* AwsApiJob::COMPONENT_DISPLAY_NAME = "AWSCoreFramework"; @@ -29,6 +33,14 @@ namespace AWSCore config.userAgent = "/O3DE_AwsApiJob"; config.requestTimeoutMs = 30000; config.connectTimeoutMs = 30000; + + // Instructs the HTTP client where to find the SSL certificate trust store. + // It is required to copy the cacert.pem to the expected file path for running the Android client. + Aws::String caFilePath = Platform::GetCaCertBundlePath(); + if (!caFilePath.empty()) + { + config.caFile = caFilePath; + } } ); }; diff --git a/Gems/AWSCore/Code/Source/Framework/Platform/Android/GetCertsPath_Android.cpp b/Gems/AWSCore/Code/Source/Framework/Platform/Android/GetCertsPath_Android.cpp new file mode 100644 index 0000000000..b0d97e3ddd --- /dev/null +++ b/Gems/AWSCore/Code/Source/Framework/Platform/Android/GetCertsPath_Android.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +// The AWS Native SDK AWSAllocator triggers a warning due to accessing members of std::allocator directly. +// AWSAllocator.h(70): warning C4996: 'std::allocator::pointer': warning STL4010: Various members of std::allocator are deprecated in +// C++17. Use std::allocator_traits instead of accessing these members directly. You can define +// _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received +// this warning. +AZ_PUSH_DISABLE_WARNING(4251 4996, "-Wunknown-warning-option") +#include +AZ_POP_DISABLE_WARNING +#include +#include + +namespace AWSCore +{ + namespace Platform + { + Aws::String GetCaCertBundlePath() + { + AZStd::string publicStoragePath = AZ::Android::Utils::GetAppPublicStoragePath(); + publicStoragePath.append("/certificates/aws/cacert.pem"); + + return publicStoragePath.c_str(); + } + } // namespace Platform +} diff --git a/Gems/AWSCore/Code/Source/Framework/Platform/Android/platform_android_files.cmake b/Gems/AWSCore/Code/Source/Framework/Platform/Android/platform_android_files.cmake new file mode 100644 index 0000000000..22d9681e3f --- /dev/null +++ b/Gems/AWSCore/Code/Source/Framework/Platform/Android/platform_android_files.cmake @@ -0,0 +1,10 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# + +set(FILES + GetCertsPath_Android.cpp +) diff --git a/Gems/AWSCore/Code/Source/Framework/Platform/Common/GetCertsPath_Null.cpp b/Gems/AWSCore/Code/Source/Framework/Platform/Common/GetCertsPath_Null.cpp new file mode 100644 index 0000000000..3bc9739e56 --- /dev/null +++ b/Gems/AWSCore/Code/Source/Framework/Platform/Common/GetCertsPath_Null.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +// The AWS Native SDK AWSAllocator triggers a warning due to accessing members of std::allocator directly. +// AWSAllocator.h(70): warning C4996: 'std::allocator::pointer': warning STL4010: Various members of std::allocator are deprecated in +// C++17. Use std::allocator_traits instead of accessing these members directly. You can define +// _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received +// this warning. +AZ_PUSH_DISABLE_WARNING(4251 4996, "-Wunknown-warning-option") +#include +AZ_POP_DISABLE_WARNING + +namespace AWSCore +{ + namespace Platform + { + Aws::String GetCaCertBundlePath() + { + return ""; // no-op + } + } // namespace Platform +} // namespace GridMate diff --git a/Gems/AWSCore/Code/Source/Framework/Platform/Linux/platform_linux_files.cmake b/Gems/AWSCore/Code/Source/Framework/Platform/Linux/platform_linux_files.cmake new file mode 100644 index 0000000000..108bdbcff1 --- /dev/null +++ b/Gems/AWSCore/Code/Source/Framework/Platform/Linux/platform_linux_files.cmake @@ -0,0 +1,10 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# + +set(FILES + ../Common/GetCertsPath_Null.cpp +) diff --git a/Gems/AWSCore/Code/Source/Framework/Platform/Mac/platform_mac_files.cmake b/Gems/AWSCore/Code/Source/Framework/Platform/Mac/platform_mac_files.cmake new file mode 100644 index 0000000000..108bdbcff1 --- /dev/null +++ b/Gems/AWSCore/Code/Source/Framework/Platform/Mac/platform_mac_files.cmake @@ -0,0 +1,10 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# + +set(FILES + ../Common/GetCertsPath_Null.cpp +) diff --git a/Gems/AWSCore/Code/Source/Framework/Platform/Windows/platform_windows_files.cmake b/Gems/AWSCore/Code/Source/Framework/Platform/Windows/platform_windows_files.cmake new file mode 100644 index 0000000000..108bdbcff1 --- /dev/null +++ b/Gems/AWSCore/Code/Source/Framework/Platform/Windows/platform_windows_files.cmake @@ -0,0 +1,10 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# + +set(FILES + ../Common/GetCertsPath_Null.cpp +) diff --git a/Gems/AWSCore/Code/Source/Framework/Platform/iOS/platform_ios_files.cmake b/Gems/AWSCore/Code/Source/Framework/Platform/iOS/platform_ios_files.cmake new file mode 100644 index 0000000000..108bdbcff1 --- /dev/null +++ b/Gems/AWSCore/Code/Source/Framework/Platform/iOS/platform_ios_files.cmake @@ -0,0 +1,10 @@ +# +# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. +# +# SPDX-License-Identifier: Apache-2.0 OR MIT +# +# + +set(FILES + ../Common/GetCertsPath_Null.cpp +) From 6b6bd1149d007330c30f3531737ef53178c2ccf0 Mon Sep 17 00:00:00 2001 From: onecent1101 Date: Mon, 12 Jul 2021 14:17:33 -0700 Subject: [PATCH 26/53] [SPEC-7510] Remove unnecessary static container for AWSCore scriptcanvas nodes Signed-off-by: onecent1101 --- .../ScriptCanvas/AWSScriptBehaviorBase.h | 42 ------------ .../ScriptCanvas/AWSScriptBehaviorDynamoDB.h | 10 +-- .../ScriptCanvas/AWSScriptBehaviorLambda.h | 10 +-- .../Public/ScriptCanvas/AWSScriptBehaviorS3.h | 10 +-- .../AWSScriptBehaviorsComponent.h | 16 ----- .../AWSScriptBehaviorDynamoDB.cpp | 43 +++++-------- .../ScriptCanvas/AWSScriptBehaviorLambda.cpp | 43 +++++-------- .../ScriptCanvas/AWSScriptBehaviorS3.cpp | 64 ++++++++----------- .../AWSScriptBehaviorsComponent.cpp | 56 +--------------- .../AWSScriptBehaviorsComponentTest.cpp | 28 ++------ Gems/AWSCore/Code/awscore_files.cmake | 1 - 11 files changed, 88 insertions(+), 235 deletions(-) delete mode 100644 Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorBase.h diff --git a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorBase.h b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorBase.h deleted file mode 100644 index 90163dd363..0000000000 --- a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorBase.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -namespace AZ -{ - class BehaviorContext; - class EditContext; - class SerializeContext; -} // namespace AZ - -// this just provides a convenient template to avoid the necessary boilerplate when you derive from AWSScriptBehaviorBase -#define AWS_SCRIPT_BEHAVIOR_DEFINITION(className, guidString) \ - AZ_TYPE_INFO(className, guidString) \ - AZ_CLASS_ALLOCATOR(className, AZ::SystemAllocator, 0) \ - void ReflectSerialization(AZ::SerializeContext* serializeContext) override; \ - void ReflectBehaviors(AZ::BehaviorContext* behaviorContext) override; \ - void ReflectEditParameters(AZ::EditContext* editContext) override; \ - className(); \ - -namespace AWSCore -{ - //! An interface for AWS ScriptCanvas Behaviors to inherit from - class AWSScriptBehaviorBase - { - public: - virtual ~AWSScriptBehaviorBase() = default; - - virtual void ReflectSerialization(AZ::SerializeContext* reflectContext) = 0; - virtual void ReflectBehaviors(AZ::BehaviorContext* behaviorContext) = 0; - virtual void ReflectEditParameters(AZ::EditContext* editContext) = 0; - - virtual void Init() {} - virtual void Activate() {} - virtual void Deactivate() {} - }; -} // namespace AWSCore diff --git a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorDynamoDB.h b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorDynamoDB.h index 317d16dbe4..7244f57f6a 100644 --- a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorDynamoDB.h +++ b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorDynamoDB.h @@ -10,8 +10,6 @@ #include #include -#include - namespace AWSCore { using DynamoDBAttributeValueMap = AZStd::unordered_map; @@ -55,10 +53,14 @@ namespace AWSCore }; class AWSScriptBehaviorDynamoDB - : public AWSScriptBehaviorBase { public: - AWS_SCRIPT_BEHAVIOR_DEFINITION(AWSScriptBehaviorDynamoDB, "{569E74F6-1268-4199-9653-A3B603FC9F4F}"); + AZ_RTTI(AWSScriptBehaviorDynamoDB, "{569E74F6-1268-4199-9653-A3B603FC9F4F}"); + + AWSScriptBehaviorDynamoDB() = default; + virtual ~AWSScriptBehaviorDynamoDB() = default; + + static void Reflect(AZ::ReflectContext* context); static void GetItem(const AZStd::string& tableResourceKey, const DynamoDBAttributeValueMap& keyMap); static void GetItemRaw(const AZStd::string& table, const DynamoDBAttributeValueMap& keyMap, const AZStd::string& region); diff --git a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorLambda.h b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorLambda.h index a8a807e7fb..64601d8e59 100644 --- a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorLambda.h +++ b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorLambda.h @@ -10,8 +10,6 @@ #include #include -#include - namespace AWSCore { //! AWS Script Behavior notifications for ScriptCanvas behaviors that interact with AWS Lambda @@ -53,10 +51,14 @@ namespace AWSCore }; class AWSScriptBehaviorLambda - : public AWSScriptBehaviorBase { public: - AWS_SCRIPT_BEHAVIOR_DEFINITION(AWSScriptBehaviorLambda, "{9E71534D-34B3-4723-B180-2552513DDA3D}"); + AZ_RTTI(AWSScriptBehaviorLambda, "{9E71534D-34B3-4723-B180-2552513DDA3D}"); + + AWSScriptBehaviorLambda() = default; + virtual ~AWSScriptBehaviorLambda() = default; + + static void Reflect(AZ::ReflectContext* context); static void Invoke(const AZStd::string& functionResourceKey, const AZStd::string& payload); static void InvokeRaw(const AZStd::string& functionName, const AZStd::string& payload, const AZStd::string& region); diff --git a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h index a75c3bce31..ac2df1c822 100644 --- a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h +++ b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h @@ -10,8 +10,6 @@ #include #include -#include - namespace AWSCore { //! AWS Script Behavior notifications for ScriptCanvas behaviors that interact with AWS S3 @@ -68,7 +66,6 @@ namespace AWSCore }; class AWSScriptBehaviorS3 - : public AWSScriptBehaviorBase { static constexpr const char AWSScriptBehaviorS3Name[] = "AWSScriptBehaviorS3"; static constexpr const char OutputFileIsEmptyErrorMessage[] = "Request validation failed, output file is empty."; @@ -81,7 +78,12 @@ namespace AWSCore static constexpr const char RegionNameIsEmptyErrorMessage[] = "Request validation failed, region name is empty."; public: - AWS_SCRIPT_BEHAVIOR_DEFINITION(AWSScriptBehaviorS3, "{7F4E956C-7463-4236-B320-C992D36A9C6E}"); + AZ_RTTI(AWSScriptBehaviorS3, "{7F4E956C-7463-4236-B320-C992D36A9C6E}"); + + AWSScriptBehaviorS3() = default; + virtual ~AWSScriptBehaviorS3() = default; + + static void Reflect(AZ::ReflectContext* context); static void GetObject(const AZStd::string& bucketResourceKey, const AZStd::string& objectKey, const AZStd::string& outFile); static void GetObjectRaw(const AZStd::string& bucket, const AZStd::string& objectKey, const AZStd::string& region, const AZStd::string& outFile); diff --git a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorsComponent.h b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorsComponent.h index 8958425615..43bd15d726 100644 --- a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorsComponent.h +++ b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorsComponent.h @@ -10,7 +10,6 @@ #include #include #include -#include namespace AWSCore { @@ -30,23 +29,8 @@ namespace AWSCore static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent); - static bool AddedBehaviours() - { - return m_alreadyAddedBehaviors; - } - - protected: - - //////////////////////////////////////////////////////////////////////// // AZ::Component interface implementation - void Init() override; void Activate() override; void Deactivate() override; - //////////////////////////////////////////////////////////////////////// - - static void AddBehaviors(); // Add any behaviors you derived from AWSScriptBehaviorBase to the implementation of this function - - static AZStd::vector> m_behaviors; - static bool m_alreadyAddedBehaviors; }; } // namespace AWSCore diff --git a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorDynamoDB.cpp b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorDynamoDB.cpp index c25df555fc..41c1aff34d 100644 --- a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorDynamoDB.cpp +++ b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorDynamoDB.cpp @@ -20,39 +20,30 @@ namespace AWSCore { - AWSScriptBehaviorDynamoDB::AWSScriptBehaviorDynamoDB() + void AWSScriptBehaviorDynamoDB::Reflect(AZ::ReflectContext* context) { - } - - void AWSScriptBehaviorDynamoDB::ReflectSerialization(AZ::SerializeContext* serializeContext) - { - if (serializeContext) + if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) { serializeContext->Class() ->Version(0); } - } - - void AWSScriptBehaviorDynamoDB::ReflectBehaviors(AZ::BehaviorContext* behaviorContext) - { - behaviorContext->Class("AWSScriptBehaviorDynamoDB") - ->Attribute(AZ::Script::Attributes::Category, "AWSCore") - ->Method("GetItem", &AWSScriptBehaviorDynamoDB::GetItem, - {{{"Table Resource KeyName", "The name of the table containing the requested item."}, - {"Key Map", "A map of attribute names to AttributeValue objects, representing the primary key of the item to retrieve."}}}) - ->Method("GetItemRaw", &AWSScriptBehaviorDynamoDB::GetItemRaw, - {{{"Table Name", "The name of the table containing the requested item."}, - {"Key Map", "A map of attribute names to AttributeValue objects, representing the primary key of the item to retrieve."}, - {"Region Name", "The region of the table located in."}}}); - behaviorContext->EBus("AWSDynamoDBBehaviorNotificationBus") - ->Attribute(AZ::Script::Attributes::Category, "AWSCore") - ->Handler(); - } + if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) + { + behaviorContext->Class("AWSScriptBehaviorDynamoDB") + ->Attribute(AZ::Script::Attributes::Category, "AWSCore") + ->Method("GetItem", &AWSScriptBehaviorDynamoDB::GetItem, + {{{"Table Resource KeyName", "The name of the table containing the requested item."}, + {"Key Map", "A map of attribute names to AttributeValue objects, representing the primary key of the item to retrieve."}}}) + ->Method("GetItemRaw", &AWSScriptBehaviorDynamoDB::GetItemRaw, + {{{"Table Name", "The name of the table containing the requested item."}, + {"Key Map", "A map of attribute names to AttributeValue objects, representing the primary key of the item to retrieve."}, + {"Region Name", "The region of the table located in."}}}); - void AWSScriptBehaviorDynamoDB::ReflectEditParameters(AZ::EditContext* editContext) - { - AZ_UNUSED(editContext); + behaviorContext->EBus("AWSDynamoDBBehaviorNotificationBus") + ->Attribute(AZ::Script::Attributes::Category, "AWSCore") + ->Handler(); + } } void AWSScriptBehaviorDynamoDB::GetItem(const AZStd::string& tableResourceKey, const DynamoDBAttributeValueMap& keyMap) diff --git a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorLambda.cpp b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorLambda.cpp index a7420654de..d4137c313b 100644 --- a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorLambda.cpp +++ b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorLambda.cpp @@ -21,39 +21,30 @@ namespace AWSCore { - AWSScriptBehaviorLambda::AWSScriptBehaviorLambda() + void AWSScriptBehaviorLambda::Reflect(AZ::ReflectContext* context) { - } - - void AWSScriptBehaviorLambda::ReflectSerialization(AZ::SerializeContext* serializeContext) - { - if (serializeContext) + if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) { serializeContext->Class() ->Version(0); } - } - - void AWSScriptBehaviorLambda::ReflectBehaviors(AZ::BehaviorContext* behaviorContext) - { - behaviorContext->Class("AWSScriptBehaviorLambda") - ->Attribute(AZ::Script::Attributes::Category, "AWSCore") - ->Method("Invoke", &AWSScriptBehaviorLambda::Invoke, - {{{"Function Resource KeyName", "The resource key name of the lambda function in resource mapping config file."}, - {"Payload", "The JSON that you want to provide to your Lambda function as input."}}}) - ->Method("InvokeRaw", &AWSScriptBehaviorLambda::InvokeRaw, - {{{"Function Name", "The name of the Lambda function, version, or alias."}, - {"Payload", "The JSON that you want to provide to your Lambda function as input."}, - {"Region Name", "The region of the lambda function located in."}}}); - behaviorContext->EBus("AWSLambdaBehaviorNotificationBus") - ->Attribute(AZ::Script::Attributes::Category, "AWSCore") - ->Handler(); - } + if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) + { + behaviorContext->Class("AWSScriptBehaviorLambda") + ->Attribute(AZ::Script::Attributes::Category, "AWSCore") + ->Method("Invoke", &AWSScriptBehaviorLambda::Invoke, + {{{"Function Resource KeyName", "The resource key name of the lambda function in resource mapping config file."}, + {"Payload", "The JSON that you want to provide to your Lambda function as input."}}}) + ->Method("InvokeRaw", &AWSScriptBehaviorLambda::InvokeRaw, + {{{"Function Name", "The name of the Lambda function, version, or alias."}, + {"Payload", "The JSON that you want to provide to your Lambda function as input."}, + {"Region Name", "The region of the lambda function located in."}}}); - void AWSScriptBehaviorLambda::ReflectEditParameters(AZ::EditContext* editContext) - { - AZ_UNUSED(editContext); + behaviorContext->EBus("AWSLambdaBehaviorNotificationBus") + ->Attribute(AZ::Script::Attributes::Category, "AWSCore") + ->Handler(); + } } void AWSScriptBehaviorLambda::Invoke(const AZStd::string& functionResourceKey, const AZStd::string& payload) diff --git a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorS3.cpp b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorS3.cpp index f47dda8046..e82fff0c31 100644 --- a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorS3.cpp +++ b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorS3.cpp @@ -24,49 +24,39 @@ namespace AWSCore { - AWSScriptBehaviorS3::AWSScriptBehaviorS3() + void AWSScriptBehaviorS3::Reflect(AZ::ReflectContext* context) { - } - - void AWSScriptBehaviorS3::ReflectSerialization(AZ::SerializeContext* serializeContext) - { - if (serializeContext) + if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) { serializeContext->Class() ->Version(0); } - } - - void AWSScriptBehaviorS3::ReflectBehaviors(AZ::BehaviorContext* behaviorContext) - { - behaviorContext->Class(AWSScriptBehaviorS3Name) - ->Attribute(AZ::Script::Attributes::Category, "AWSCore") - ->Method("GetObject", &AWSScriptBehaviorS3::GetObject, - {{{"Bucket Resource KeyName", "The resource key name of the bucket in resource mapping config file."}, - {"Object KeyName", "The object key."}, - {"Outfile Name", "Filename where the content will be saved."}}}) - ->Method("GetObjectRaw", &AWSScriptBehaviorS3::GetObjectRaw, - {{{"Bucket Name", "The name of the bucket containing the object."}, - {"Object KeyName", "The object key."}, - {"Region Name", "The region of the bucket located in."}, - {"Outfile Name", "Filename where the content will be saved."}}}) - ->Method("HeadObject", &AWSScriptBehaviorS3::HeadObject, - {{{"Bucket Resource KeyName", "The resource key name of the bucket in resource mapping config file."}, - {"Object KeyName", "The object key."}}}) - ->Method("HeadObjectRaw", &AWSScriptBehaviorS3::HeadObjectRaw, - {{{"Bucket Name", "The name of the bucket containing the object."}, - {"Object KeyName", "The object key."}, - {"Region Name", "The region of the bucket located in."}}}) - ; - - behaviorContext->EBus("AWSS3BehaviorNotificationBus") - ->Attribute(AZ::Script::Attributes::Category, "AWSCore") - ->Handler(); - } - void AWSScriptBehaviorS3::ReflectEditParameters(AZ::EditContext* editContext) - { - AZ_UNUSED(editContext); + if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) + { + behaviorContext->Class(AWSScriptBehaviorS3Name) + ->Attribute(AZ::Script::Attributes::Category, "AWSCore") + ->Method("GetObject", &AWSScriptBehaviorS3::GetObject, + {{{"Bucket Resource KeyName", "The resource key name of the bucket in resource mapping config file."}, + {"Object KeyName", "The object key."}, + {"Outfile Name", "Filename where the content will be saved."}}}) + ->Method("GetObjectRaw", &AWSScriptBehaviorS3::GetObjectRaw, + {{{"Bucket Name", "The name of the bucket containing the object."}, + {"Object KeyName", "The object key."}, + {"Region Name", "The region of the bucket located in."}, + {"Outfile Name", "Filename where the content will be saved."}}}) + ->Method("HeadObject", &AWSScriptBehaviorS3::HeadObject, + {{{"Bucket Resource KeyName", "The resource key name of the bucket in resource mapping config file."}, + {"Object KeyName", "The object key."}}}) + ->Method("HeadObjectRaw", &AWSScriptBehaviorS3::HeadObjectRaw, + {{{"Bucket Name", "The name of the bucket containing the object."}, + {"Object KeyName", "The object key."}, + {"Region Name", "The region of the bucket located in."}}}); + + behaviorContext->EBus("AWSS3BehaviorNotificationBus") + ->Attribute(AZ::Script::Attributes::Category, "AWSCore") + ->Handler(); + } } void AWSScriptBehaviorS3::GetObject( diff --git a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorsComponent.cpp b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorsComponent.cpp index 530c35cde2..4c41dc3f0e 100644 --- a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorsComponent.cpp +++ b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorsComponent.cpp @@ -12,35 +12,17 @@ namespace AWSCore { - AZStd::vector> AWSScriptBehaviorsComponent::m_behaviors; - bool AWSScriptBehaviorsComponent::m_alreadyAddedBehaviors = false; - - void AWSScriptBehaviorsComponent::AddBehaviors() - { - if (!m_alreadyAddedBehaviors) - { - // Add new script behaviors here - m_behaviors.push_back(AZStd::make_unique()); - m_behaviors.push_back(AZStd::make_unique()); - m_behaviors.push_back(AZStd::make_unique()); - m_alreadyAddedBehaviors = true; - } - } - void AWSScriptBehaviorsComponent::Reflect(AZ::ReflectContext* context) { - AddBehaviors(); + AWSScriptBehaviorDynamoDB::Reflect(context); + AWSScriptBehaviorLambda::Reflect(context); + AWSScriptBehaviorS3::Reflect(context); if (AZ::SerializeContext* serialize = azrtti_cast(context)) { serialize->Class() ->Version(0); - for (auto&& behavior : m_behaviors) - { - behavior->ReflectSerialization(serialize); - } - if (AZ::EditContext* editContext = serialize->GetEditContext()) { editContext->Class("AWSScriptBehaviors", "Provides ScriptCanvas functions for calling AWS") @@ -49,19 +31,6 @@ namespace AWSCore ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("AWS")) ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ; - - for (auto&& behavior : m_behaviors) - { - behavior->ReflectEditParameters(editContext); - } - } - } - - if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) - { - for (auto&& behavior : m_behaviors) - { - behavior->ReflectBehaviors(behaviorContext); } } } @@ -86,31 +55,12 @@ namespace AWSCore AZ_UNUSED(dependent); } - void AWSScriptBehaviorsComponent::Init() - { - for (auto&& behavior : m_behaviors) - { - behavior->Init(); - } - } - void AWSScriptBehaviorsComponent::Activate() { - for (auto&& behavior : m_behaviors) - { - behavior->Activate(); - } } void AWSScriptBehaviorsComponent::Deactivate() { - for (auto&& behavior : m_behaviors) - { - behavior->Deactivate(); - } - - // this forces the vector to release its capacity, clear/shrink_to_fit is not - m_behaviors.swap(AZStd::vector>()); } } diff --git a/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorsComponentTest.cpp b/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorsComponentTest.cpp index 15ad297f9b..2283caa69e 100644 --- a/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorsComponentTest.cpp +++ b/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorsComponentTest.cpp @@ -15,18 +15,6 @@ using namespace AWSCore; -class AWSScriptBehaviorsComponentMock - : public AWSScriptBehaviorsComponent -{ -public: - AZ_COMPONENT(AWSScriptBehaviorsComponentMock, "{78579706-E1B2-4788-A34D-A58D3F273FF9}"); - - int GetBehaviorsNum() - { - return m_behaviors.size(); - } -}; - class AWSScriptBehaviorsComponentTest : public UnitTest::ScopedAllocatorSetupFixture { @@ -38,7 +26,7 @@ public: m_behaviorContext = AZStd::make_unique(); m_entity = AZStd::make_unique(); - m_scriptBehaviorsComponent.reset(m_entity->CreateComponent()); + m_scriptBehaviorsComponent.reset(m_entity->CreateComponent()); } void TearDown() override @@ -56,20 +44,16 @@ protected: AZStd::unique_ptr m_serializeContext; AZStd::unique_ptr m_behaviorContext; AZStd::unique_ptr m_componentDescriptor; - AZStd::unique_ptr m_scriptBehaviorsComponent; + AZStd::unique_ptr m_scriptBehaviorsComponent; AZStd::unique_ptr m_entity; }; -TEST_F(AWSScriptBehaviorsComponentTest, InitActivateDeactivate_Call_GetExpectedNumOfAddedBehaviors) +TEST_F(AWSScriptBehaviorsComponentTest, Reflect) { - m_componentDescriptor.reset(AWSScriptBehaviorsComponentMock::CreateDescriptor()); + int oldEBusNum = m_behaviorContext->m_ebuses.size(); + m_componentDescriptor.reset(AWSScriptBehaviorsComponent::CreateDescriptor()); m_componentDescriptor->Reflect(m_serializeContext.get()); m_componentDescriptor->Reflect(m_behaviorContext.get()); - EXPECT_TRUE(AWSScriptBehaviorsComponentMock::AddedBehaviours()); - EXPECT_TRUE(m_scriptBehaviorsComponent->GetBehaviorsNum() == 3); - m_entity->Init(); - m_entity->Activate(); - m_entity->Deactivate(); - EXPECT_TRUE(m_scriptBehaviorsComponent->GetBehaviorsNum() == 0); + EXPECT_TRUE(m_behaviorContext->m_ebuses.size() - oldEBusNum == 3); } diff --git a/Gems/AWSCore/Code/awscore_files.cmake b/Gems/AWSCore/Code/awscore_files.cmake index c1577ec1eb..8e8ed280f8 100644 --- a/Gems/AWSCore/Code/awscore_files.cmake +++ b/Gems/AWSCore/Code/awscore_files.cmake @@ -32,7 +32,6 @@ set(FILES Include/Public/Framework/ServiceRequestJobConfig.h Include/Public/Framework/Util.h Include/Public/ResourceMapping/AWSResourceMappingBus.h - Include/Public/ScriptCanvas/AWSScriptBehaviorBase.h Include/Public/ScriptCanvas/AWSScriptBehaviorDynamoDB.h Include/Public/ScriptCanvas/AWSScriptBehaviorLambda.h Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h From 7937ece77323c30def9d01bcb3748dc3d14e6795 Mon Sep 17 00:00:00 2001 From: AMZN-ScottR <24445312+AMZN-ScottR@users.noreply.github.com> Date: Tue, 13 Jul 2021 15:07:16 -0700 Subject: [PATCH 27/53] [mobile-settings-crash-fix] update mobile settings editor tool to support new project path structure Signed-off-by: AMZN-ScottR <24445312+AMZN-ScottR@users.noreply.github.com> --- .../ProjectSettingsToolWindow.cpp | 36 +++++++++++-------- .../ProjectSettingsToolWindow.h | 4 +-- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp b/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp index f4e4fed973..8222c52193 100644 --- a/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp +++ b/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp @@ -20,8 +20,9 @@ #include "ValidationHandler.h" #include +#include -#include "AzToolsFramework/UI/PropertyEditor/InstanceDataHierarchy.h" +#include #include #include #include @@ -52,7 +53,7 @@ namespace ProjectSettingsTool PlatformEnabled(PlatformId::Ios) ? ProjectSettingsContainer::PlistInitVector({ ProjectSettingsContainer::PlatformAndPath - { PlatformId::Ios, m_projectRoot + PlatformResourcesFolder(PlatformId::Ios) } + { PlatformId::Ios, GetPlatformResource(PlatformId::Ios) } }) : ProjectSettingsContainer::PlistInitVector()) @@ -647,33 +648,38 @@ namespace ProjectSettingsTool // iOS can be disabled if the plist file is missing if (platformId == PlatformId::Ios) { - const AZStd::string filename = m_projectRoot + PlatformResourcesFolder(platformId); - return CFileUtil::FileExists(filename.c_str()); + AZStd::string plistPath = GetPlatformResource(platformId); + return !plistPath.empty(); } return true; } - const char* ProjectSettingsToolWindow::PlatformResourcesFolder(PlatformId platformId) + AZStd::string ProjectSettingsToolWindow::GetPlatformResource(PlatformId platformId) { if (platformId == PlatformId::Ios) { - const AZStd::string firstfilename = m_projectRoot + "/Gem/Resources/Platform/iOS/Info.plist"; - if (CFileUtil::FileExists(firstfilename.c_str())) - { - return "/Gem/Resources/Platform/iOS/Info.plist"; - } - else + const char* searchPaths[] = { + "Resources/Platform/iOS/Info.plist", + + // legacy paths + "Gem/Resources/Platform/iOS/Info.plist", + "Gem/Resources/IOSLauncher/Info.plist", + }; + + for (auto relPath : searchPaths) { - const AZStd::string filename = m_projectRoot + "/Gem/Resources/IOSLauncher/Info.plist"; - if (CFileUtil::FileExists(filename.c_str())) + AZ::IO::FixedMaxPath projectPlist{ m_projectRoot }; + projectPlist /= relPath; + + if (CFileUtil::FileExists(projectPlist.c_str())) { - return "/Gem/Resources/IOSLauncher/Info.plist"; + return projectPlist.LexicallyNormal().c_str(); } } } - return nullptr; + return AZStd::string(); } #include diff --git a/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.h b/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.h index 8979672f99..64a6646e7f 100644 --- a/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.h +++ b/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.h @@ -137,8 +137,8 @@ namespace ProjectSettingsTool // returns true if the platform is enabled bool PlatformEnabled(PlatformId platformId); - // returns the resource folder - const char* PlatformResourcesFolder(PlatformId platformId); + // returns the main platform specific resource file e.g. for iOS it would be the Info.plist + AZStd::string GetPlatformResource(PlatformId platformId); // The ui for the window QScopedPointer m_ui; From 201a387c7e5f8baa992cba198df876b6f6415ded Mon Sep 17 00:00:00 2001 From: AMZN-ScottR <24445312+AMZN-ScottR@users.noreply.github.com> Date: Tue, 13 Jul 2021 17:46:35 -0700 Subject: [PATCH 28/53] [mobile-settings-crash-fix] removed dep on FileUtil in ProjectSettingsToolWindow.cpp and optimize return in GetPlatformResource Signed-off-by: AMZN-ScottR <24445312+AMZN-ScottR@users.noreply.github.com> --- .../ProjectSettingsTool/ProjectSettingsToolWindow.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp b/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp index 8222c52193..63ce446e97 100644 --- a/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp +++ b/Code/Editor/Plugins/ProjectSettingsTool/ProjectSettingsToolWindow.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -672,9 +671,9 @@ namespace ProjectSettingsTool AZ::IO::FixedMaxPath projectPlist{ m_projectRoot }; projectPlist /= relPath; - if (CFileUtil::FileExists(projectPlist.c_str())) + if (AZ::IO::SystemFile::Exists(projectPlist.c_str())) { - return projectPlist.LexicallyNormal().c_str(); + return projectPlist.LexicallyNormal().String(); } } } From 11327b59eabf5c4c457c9d6004ea66dc9701755e Mon Sep 17 00:00:00 2001 From: Jeremy Ong Date: Tue, 13 Jul 2021 23:54:06 -0400 Subject: [PATCH 29/53] Expose vsync interval with new cvar rpi_vsync_interval and support Vulkan vsync (#2061) * Expose vsync interval with new cvar rpi_vsync_interval On change, the rpi_vsync_interval is broadcasted to a new event on the WindowNotificationBus and all swapchains are recreated with the new vsync value. Signed-off-by: Jeremy Ong * Add vsync interval support to the Vulkan RHI Vsync intervals are not intrinsically supported using the Vulkan swapchain extension. Instead, extra presents are enqueued for each extra vblank requested past 1. Swapchain recreation is triggered when transitioning to and from the FIFO presentation mode (when rpi_vsync_interval transitions from and to 0 respectively). Signed-off-by: Jeremy Ong * Rollback vsync > 1 implementation on Vulkan and leverage *Internal pattern Signed-off-by: Jeremy Ong --- .../AzFramework/Windowing/WindowBus.h | 3 ++ .../RHI/Code/Include/Atom/RHI/SwapChain.h | 5 +++ Gems/Atom/RHI/Code/Source/RHI/SwapChain.cpp | 4 ++ .../RHI/Vulkan/Code/Source/RHI/SwapChain.cpp | 40 ++++++++++++++----- .../RHI/Vulkan/Code/Source/RHI/SwapChain.h | 7 ++-- .../Include/Atom/RPI.Public/WindowContext.h | 1 + .../Code/Source/RPI.Public/WindowContext.cpp | 26 +++++++++++- 7 files changed, 73 insertions(+), 13 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h b/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h index f21993b80a..0369e703b5 100644 --- a/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h +++ b/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h @@ -97,6 +97,9 @@ namespace AzFramework //! This is called when the window is deactivated from code or if the user closes the window. virtual void OnWindowClosed() {}; + + //! This is called when vsync interval is changed. + virtual void OnVsyncIntervalChanged(uint32_t interval) { AZ_UNUSED(interval); }; }; using WindowNotificationBus = AZ::EBus; diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/SwapChain.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/SwapChain.h index ae4c0dce57..03b7b8831f 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/SwapChain.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/SwapChain.h @@ -123,6 +123,11 @@ namespace AZ /// Returns the index of the current image after the swap. virtual uint32_t PresentInternal() = 0; + virtual void SetVerticalSyncIntervalInternal(uint32_t previousVerticalSyncInterval) + { + AZ_UNUSED(previousVerticalSyncInterval); + } + ////////////////////////////////////////////////////////////////////////// SwapChainDescriptor m_descriptor; diff --git a/Gems/Atom/RHI/Code/Source/RHI/SwapChain.cpp b/Gems/Atom/RHI/Code/Source/RHI/SwapChain.cpp index 5d1d938fc8..d0db51ece5 100644 --- a/Gems/Atom/RHI/Code/Source/RHI/SwapChain.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI/SwapChain.cpp @@ -168,7 +168,11 @@ namespace AZ void SwapChain::SetVerticalSyncInterval(uint32_t verticalSyncInterval) { + uint32_t previousVsyncInterval = m_descriptor.m_verticalSyncInterval; + m_descriptor.m_verticalSyncInterval = verticalSyncInterval; + + SetVerticalSyncIntervalInternal(previousVsyncInterval); } const AttachmentId& SwapChain::GetAttachmentId() const diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/SwapChain.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/SwapChain.cpp index d356d61cef..0935e1acd8 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/SwapChain.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/SwapChain.cpp @@ -56,6 +56,18 @@ namespace AZ m_swapChainBarrier.m_isValid = true; } + void SwapChain::SetVerticalSyncIntervalInternal(uint32_t previousVsyncInterval) + { + uint32_t verticalSyncInterval = GetDescriptor().m_verticalSyncInterval; + if (verticalSyncInterval == 0 || previousVsyncInterval == 0) + { + // The presentation mode may change when transitioning to or from a vsynced presentation mode + // In this case, the swapchain must be recreated. + InvalidateNativeSwapChain(); + BuildNativeSwapChain(GetDescriptor().m_dimensions, verticalSyncInterval); + } + } + void SwapChain::SetNameInternal(const AZStd::string_view& name) { if (IsInitialized() && !name.empty()) @@ -84,7 +96,7 @@ namespace AZ auto& presentationQueue = device.GetCommandQueueContext().GetOrCreatePresentationCommandQueue(*this); m_presentationQueue = &presentationQueue; - result = BuildNativeSwapChain(swapchainDimensions); + result = BuildNativeSwapChain(swapchainDimensions, descriptor.m_verticalSyncInterval); RETURN_RESULT_IF_UNSUCCESSFUL(result); uint32_t imageCount = 0; VkResult vkResult = vkGetSwapchainImagesKHR(device.GetNativeDevice(), m_nativeSwapChain, &imageCount, nullptr); @@ -166,7 +178,7 @@ namespace AZ auto& presentationQueue = device.GetCommandQueueContext().GetOrCreatePresentationCommandQueue(*this); m_presentationQueue = &presentationQueue; - BuildNativeSwapChain(resizeDimensions); + BuildNativeSwapChain(resizeDimensions, GetDescriptor().m_verticalSyncInterval); resizeDimensions.m_imageCount = 0; VkResult vkResult = vkGetSwapchainImagesKHR(device.GetNativeDevice(), m_nativeSwapChain, &resizeDimensions.m_imageCount, nullptr); @@ -256,7 +268,8 @@ namespace AZ info.pImageIndices = &imageIndex; info.pResults = nullptr; - const VkResult result = vkQueuePresentKHR(vulkanQueue->GetNativeQueue(), &info); + VkResult result = vkQueuePresentKHR(vulkanQueue->GetNativeQueue(), &info); + // Resizing window cause recreation of SwapChain after calling this method, // so VK_SUBOPTIMAL_KHR or VK_ERROR_OUT_OF_DATE_KHR should not happen at this point. AZ_Assert(result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR, "Failed to present swapchain %s", GetName().GetCStr()); @@ -321,9 +334,17 @@ namespace AZ return surfaceFormats[0]; } - VkPresentModeKHR SwapChain::GetSupportedPresentMode() const + VkPresentModeKHR SwapChain::GetSupportedPresentMode(uint32_t verticalSyncInterval) const { AZ_Assert(m_surface, "Surface has not been initialized."); + + if (verticalSyncInterval > 0) + { + // When a non-zero vsync interval is requested, the FIFO presentation mode (always available) + // is usable without needing to query available presentation modes. + return VK_PRESENT_MODE_FIFO_KHR; + } + auto& device = static_cast(GetDevice()); const auto& physicalDevice = static_cast(device.GetPhysicalDevice()); @@ -335,12 +356,12 @@ namespace AZ AZStd::vector supportedModes(modeCount); AssertSuccess(vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice.GetNativePhysicalDevice(), m_surface->GetNativeSurface(), &modeCount, supportedModes.data())); - VkPresentModeKHR preferedModes[] = {VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR}; - for (VkPresentModeKHR preferedMode : preferedModes) + VkPresentModeKHR preferredModes[] = {VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR}; + for (VkPresentModeKHR preferredMode : preferredModes) { for (VkPresentModeKHR supportedMode : supportedModes) { - if (supportedMode == preferedMode) + if (supportedMode == preferredMode) { return supportedMode; } @@ -370,7 +391,7 @@ namespace AZ return VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; } - RHI::ResultCode SwapChain::BuildNativeSwapChain(const RHI::SwapChainDimensions& dimensions) + RHI::ResultCode SwapChain::BuildNativeSwapChain(const RHI::SwapChainDimensions& dimensions, uint32_t verticalSyncInterval) { AZ_Assert(m_nativeSwapChain == VK_NULL_HANDLE, "Vulkan's native SwapChain has been initialized already."); auto& device = static_cast(GetDevice()); @@ -421,7 +442,7 @@ namespace AZ createInfo.pQueueFamilyIndices = familyIndices.empty() ? nullptr : familyIndices.data(); createInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; createInfo.compositeAlpha = GetSupportedCompositeAlpha(); - createInfo.presentMode = GetSupportedPresentMode(); + createInfo.presentMode = GetSupportedPresentMode(verticalSyncInterval); createInfo.clipped = VK_FALSE; createInfo.oldSwapchain = VK_NULL_HANDLE; @@ -442,6 +463,7 @@ namespace AZ imageAvailableSemaphore->GetNativeSemaphore(), VK_NULL_HANDLE, acquiredImageIndex); + // Resizing window cause recreation of SwapChain before calling this method, // so VK_SUBOPTIMAL_KHR or VK_ERROR_OUT_OF_DATE_KHR should not happen. AssertSuccess(vkResult); diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/SwapChain.h b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/SwapChain.h index b77c305e46..475375a5b3 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/SwapChain.h +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/SwapChain.h @@ -49,7 +49,7 @@ namespace AZ const CommandQueue& GetPresentationQueue() const; void QueueBarrier(const VkPipelineStageFlags src, const VkPipelineStageFlags dst, const VkImageMemoryBarrier& imageBarrier); - + private: SwapChain() = default; @@ -65,14 +65,15 @@ namespace AZ RHI::ResultCode InitImageInternal(const RHI::SwapChain::InitImageRequest& request) override; RHI::ResultCode ResizeInternal(const RHI::SwapChainDimensions& dimensions, RHI::SwapChainDimensions* nativeDimensions) override; uint32_t PresentInternal() override; + void SetVerticalSyncIntervalInternal(uint32_t previousVsyncInterval) override; ////////////////////////////////////////////////////////////////////// RHI::ResultCode BuildSurface(const RHI::SwapChainDescriptor& descriptor); bool ValidateSurfaceDimensions(const RHI::SwapChainDimensions& dimensions); VkSurfaceFormatKHR GetSupportedSurfaceFormat(const RHI::Format format) const; - VkPresentModeKHR GetSupportedPresentMode() const; + VkPresentModeKHR GetSupportedPresentMode(uint32_t verticalSyncInterval) const; VkCompositeAlphaFlagBitsKHR GetSupportedCompositeAlpha() const; - RHI::ResultCode BuildNativeSwapChain(const RHI::SwapChainDimensions& dimensions); + RHI::ResultCode BuildNativeSwapChain(const RHI::SwapChainDimensions& dimensions, uint32_t verticalSyncInterval); RHI::ResultCode AcquireNewImage(uint32_t* acquiredImageIndex); void InvalidateSurface(); diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/WindowContext.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/WindowContext.h index fc809c7d39..9f2f40fbbe 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/WindowContext.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Public/WindowContext.h @@ -71,6 +71,7 @@ namespace AZ // WindowNotificationBus::Handler overrides ... void OnWindowResized(uint32_t width, uint32_t height) override; void OnWindowClosed() override; + void OnVsyncIntervalChanged(uint32_t interval) override; // ExclusiveFullScreenRequestBus::Handler overrides ... bool IsExclusiveFullScreenPreferred() const override; diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/WindowContext.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/WindowContext.cpp index 7a5982c10d..16ad7a1155 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/WindowContext.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/WindowContext.cpp @@ -13,6 +13,22 @@ #include +#include +#include + + +void OnVsyncIntervalChanged(uint32_t const& interval) +{ + AzFramework::WindowNotificationBus::Broadcast( + &AzFramework::WindowNotificationBus::Events::OnVsyncIntervalChanged, + AZ::GetClamp(interval, 0u, 4u)); +} + +// NOTE: On change, broadcasts the new requested vsync interval to all windows. +// The value of the vsync interval is constrained between 0 and 4 +// Vsync intervals greater than 1 are not currently supported on the Vulkan RHI (see #2061 for discussion) +AZ_CVAR(uint32_t, rpi_vsync_interval, 0, OnVsyncIntervalChanged, AZ::ConsoleFunctorFlags::Null, "Set swapchain vsync interval"); + namespace AZ { namespace RPI @@ -103,6 +119,14 @@ namespace AZ AzFramework::WindowNotificationBus::Handler::BusDisconnect(m_windowHandle); } + void WindowContext::OnVsyncIntervalChanged(uint32_t interval) + { + if (m_swapChain->GetDescriptor().m_verticalSyncInterval != interval) + { + m_swapChain->SetVerticalSyncInterval(interval); + } + } + bool WindowContext::IsExclusiveFullScreenPreferred() const { return m_swapChain->IsExclusiveFullScreenPreferred(); @@ -135,7 +159,7 @@ namespace AZ RHI::SwapChainDescriptor descriptor; descriptor.m_window = windowHandle; - descriptor.m_verticalSyncInterval = 0; + descriptor.m_verticalSyncInterval = rpi_vsync_interval; descriptor.m_dimensions.m_imageWidth = width; descriptor.m_dimensions.m_imageHeight = height; descriptor.m_dimensions.m_imageCount = 3; From 867ae23664844658ba2d522c2212e9b5ea0afa17 Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Tue, 13 Jul 2021 20:58:48 -0700 Subject: [PATCH 30/53] Make Viewport input events fully Qt based (#2142) * Make Viewport input events fully Qt based. This should fix an issue with Qt touch event -> mouse event translation in the Editor, and may also fix issues with the Mac Editor and remote desktop (though, lacking the requisite hardware, I can test precisely none of these things personally). See https://github.com/o3de/o3de/issues/1889 - Adapted LegacyViewportCameraController to use Movement::X & Y (mostly for testing purposes, it's on the slate for being removed soon) - Moved cursor capture logic from RenderViewportWidget into QtEventToAzInputManager so that it can make sure it generates correct movement deltas - Removed ViewportMouseCursorRequests::PreviousViewportCursorScreenPosition to have our viewport controllers use our dedicated Movement::X and Y channels instead, which will work in the launcher Signed-off-by: nvsickle * Address review feedback Signed-off-by: nvsickle * Fix Linux build Signed-off-by: nvsickle --- .../Editor/LegacyViewportCameraController.cpp | 39 ++++++----- Code/Editor/LegacyViewportCameraController.h | 2 +- .../Input/QtEventToAzInputManager.cpp | 67 ++++++++++++++++--- .../Input/QtEventToAzInputManager.h | 13 ++++ .../Viewport/ViewportMessages.h | 5 -- .../Viewport/RenderViewportWidget.h | 3 - .../Source/Viewport/RenderViewportWidget.cpp | 36 +--------- 7 files changed, 93 insertions(+), 72 deletions(-) diff --git a/Code/Editor/LegacyViewportCameraController.cpp b/Code/Editor/LegacyViewportCameraController.cpp index f437196548..b18e807942 100644 --- a/Code/Editor/LegacyViewportCameraController.cpp +++ b/Code/Editor/LegacyViewportCameraController.cpp @@ -83,9 +83,9 @@ AZ::RPI::ViewportContextPtr LegacyViewportCameraControllerInstance::GetViewportC } bool LegacyViewportCameraControllerInstance::HandleMouseMove( - const AzFramework::ScreenPoint& currentMousePos, const AzFramework::ScreenPoint& previousMousePos) + int dx, int dy) { - if (previousMousePos == currentMousePos) + if (dx == 0 && dy == 0) { return false; } @@ -105,7 +105,7 @@ bool LegacyViewportCameraControllerInstance::HandleMouseMove( if (m_inMoveMode || m_inOrbitMode || m_inRotateMode || m_inZoomMode) { - m_totalMouseMoveDelta += (QPoint(currentMousePos.m_x, currentMousePos.m_y)-QPoint(previousMousePos.m_x, previousMousePos.m_y)).manhattanLength(); + m_totalMouseMoveDelta += AZStd::abs(dx) + AZStd::abs(dy); } if ((m_inRotateMode && m_inMoveMode) || m_inZoomMode) @@ -115,7 +115,7 @@ bool LegacyViewportCameraControllerInstance::HandleMouseMove( Vec3 ydir = m.GetColumn1().GetNormalized(); Vec3 pos = m.GetTranslation(); - const float posDelta = 0.2f * (previousMousePos.m_y - currentMousePos.m_y) * speedScale; + const float posDelta = 0.2f * dy * speedScale; pos = pos - ydir * posDelta; m_orbitDistance = m_orbitDistance + posDelta; m_orbitDistance = fabs(m_orbitDistance); @@ -126,7 +126,7 @@ bool LegacyViewportCameraControllerInstance::HandleMouseMove( } else if (m_inRotateMode) { - Ang3 angles(-currentMousePos.m_y + previousMousePos.m_y, 0, -currentMousePos.m_x + previousMousePos.m_x); + Ang3 angles(dy, 0, dx); angles = angles * 0.002f * gSettings.cameraRotateSpeed; if (gSettings.invertYRotation) { @@ -158,7 +158,7 @@ bool LegacyViewportCameraControllerInstance::HandleMouseMove( } Vec3 pos = m.GetTranslation(); - pos += 0.1f * xdir * (currentMousePos.m_x - previousMousePos.m_x) * speedScale + 0.1f * zdir * (previousMousePos.m_y - currentMousePos.m_y) * speedScale; + pos += 0.1f * xdir * dx * speedScale + 0.1f * zdir * dy * speedScale; m.SetTranslation(pos); AZ::Transform transform = viewportContext->GetCameraTransform(); @@ -168,7 +168,7 @@ bool LegacyViewportCameraControllerInstance::HandleMouseMove( } else if (m_inOrbitMode) { - Ang3 angles(-currentMousePos.m_y + previousMousePos.m_y, 0, -currentMousePos.m_x + previousMousePos.m_x); + Ang3 angles(dy, 0, dx); angles = angles * 0.002f * gSettings.cameraRotateSpeed; if (gSettings.invertPan) @@ -302,20 +302,19 @@ bool LegacyViewportCameraControllerInstance::HandleInputChannelEvent(const AzFra bool shouldCaptureCursor = m_capturingCursor; bool shouldConsumeEvent = false; - if (id == AzFramework::InputDeviceMouse::SystemCursorPosition) + if (id == AzFramework::InputDeviceMouse::Movement::X || id == AzFramework::InputDeviceMouse::Movement::Y) { - bool result = false; - AzToolsFramework::ViewportInteraction::ViewportMouseCursorRequestBus::Event( - GetViewportId(), - [this, &result](AzToolsFramework::ViewportInteraction::ViewportMouseCursorRequests* mouseRequests) - { - if (auto previousMousePosition = mouseRequests->PreviousViewportCursorScreenPosition(); - previousMousePosition.has_value()) - { - result = HandleMouseMove(mouseRequests->ViewportCursorScreenPosition(), previousMousePosition.value()); - } - }); - return result; + int dx = 0; + int dy = 0; + if (id == AzFramework::InputDeviceMouse::Movement::X) + { + dx = -aznumeric_cast(event.m_inputChannel.GetValue()); + } + else + { + dy = -aznumeric_cast(event.m_inputChannel.GetValue()); + } + return HandleMouseMove(dx, dy); } else if (id == MouseButton::Left) { diff --git a/Code/Editor/LegacyViewportCameraController.h b/Code/Editor/LegacyViewportCameraController.h index d3ff439b16..ff752e27ab 100644 --- a/Code/Editor/LegacyViewportCameraController.h +++ b/Code/Editor/LegacyViewportCameraController.h @@ -69,7 +69,7 @@ namespace SandboxEditor AZ::RPI::ViewportContextPtr GetViewportContext(); - bool HandleMouseMove(const AzFramework::ScreenPoint& currentMousePos, const AzFramework::ScreenPoint& previousMousePos); + bool HandleMouseMove(int dx, int dy); bool HandleMouseWheel(float zDelta); bool IsKeyDown(Qt::Key key) const; void UpdateCursorCapture(bool shouldCaptureCursor); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.cpp index eb5034fdd5..754c04e12f 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -187,12 +188,6 @@ namespace AzToolsFramework bool QtEventToAzInputMapper::HandlesInputEvent(const AzFramework::InputChannel& channel) const { - const AzFramework::InputChannelId& channelId = channel.GetInputChannelId(); - if (channelId == AzFramework::InputDeviceMouse::Movement::X || channelId == AzFramework::InputDeviceMouse::Movement::Y) - { - return false; - } - // We map keyboard and mouse events from Qt, so flag all events coming from those devices // as handled by our synthetic event system. const AzFramework::InputDeviceId& deviceId = channel.GetInputDevice().GetInputDeviceId(); @@ -210,6 +205,22 @@ namespace AzToolsFramework } } + void QtEventToAzInputMapper::SetCursorCaptureEnabled(bool enabled) + { + if (m_capturingCursor != enabled) + { + m_capturingCursor = enabled; + if (m_capturingCursor) + { + qApp->setOverrideCursor(Qt::BlankCursor); + } + else + { + qApp->restoreOverrideCursor(); + } + } + } + bool QtEventToAzInputMapper::eventFilter(QObject* object, QEvent* event) { // Abort if processing isn't enabled. @@ -284,13 +295,25 @@ namespace AzToolsFramework { auto systemCursorChannel = GetInputChannel(AzFramework::InputDeviceMouse::SystemCursorPosition); + auto movementXChannel = + GetInputChannel(AzFramework::InputDeviceMouse::Movement::X); + auto movementYChannel = + GetInputChannel(AzFramework::InputDeviceMouse::Movement::Y); auto mouseWheelChannel = GetInputChannel(AzFramework::InputDeviceMouse::Movement::Z); systemCursorChannel->ProcessRawInputEvent(m_cursorPosition->m_normalizedPositionDelta.GetLength()); + // Generate movement events based on the pixel delta divided by the DPI scaling factor, to calculate a rough approximation + // of cursor movement velocity. + movementXChannel->ProcessRawInputEvent( + m_cursorPosition->m_normalizedPositionDelta.GetX() * aznumeric_cast(m_sourceWidget->width()) / m_sourceWidget->devicePixelRatioF()); + movementYChannel->ProcessRawInputEvent( + m_cursorPosition->m_normalizedPositionDelta.GetY() * aznumeric_cast(m_sourceWidget->height()) / m_sourceWidget->devicePixelRatioF()); mouseWheelChannel->ProcessRawInputEvent(0.f); NotifyUpdateChannelIfNotIdle(systemCursorChannel, nullptr); + NotifyUpdateChannelIfNotIdle(movementXChannel, nullptr); + NotifyUpdateChannelIfNotIdle(movementYChannel, nullptr); NotifyUpdateChannelIfNotIdle(mouseWheelChannel, nullptr); } @@ -318,16 +341,42 @@ namespace AzToolsFramework } } + AZ::Vector2 QtEventToAzInputMapper::WidgetPositionToNormalizedPosition(QPoint position) + { + const float normalizedX = aznumeric_cast(position.x()) / aznumeric_cast(m_sourceWidget->width()); + const float normalizedY = aznumeric_cast(position.y()) / aznumeric_cast(m_sourceWidget->height()); + return AZ::Vector2{normalizedX, normalizedY}; + } + + QPoint QtEventToAzInputMapper::NormalizedPositionToWidgetPosition(AZ::Vector2 normalizedPosition) + { + const int denormalizedX = aznumeric_cast(normalizedPosition.GetX() * m_sourceWidget->width()); + const int denormalizedY = aznumeric_cast(normalizedPosition.GetY() * m_sourceWidget->height()); + return QPoint{denormalizedX, denormalizedY}; + } + void QtEventToAzInputMapper::HandleMouseMoveEvent(QMouseEvent* mouseEvent) { + AZ::Vector2 lastCursorPosition = m_cursorPosition->m_normalizedPosition; + const QPoint mousePos = mouseEvent->pos(); - const float normalizedX = aznumeric_cast(mousePos.x()) / aznumeric_cast(m_sourceWidget->width()); - const float normalizedY = aznumeric_cast(mousePos.y()) / aznumeric_cast(m_sourceWidget->height()); - const AZ::Vector2 normalizedPosition(normalizedX, normalizedY); + const AZ::Vector2 normalizedPosition = WidgetPositionToNormalizedPosition(mousePos); m_cursorPosition->m_normalizedPositionDelta = normalizedPosition - m_cursorPosition->m_normalizedPosition; m_cursorPosition->m_normalizedPosition = normalizedPosition; ProcessPendingMouseEvents(); m_mouseChannelsNeedUpdate = true; + + if (m_capturingCursor) + { + // Reset our cursor position to the previous point. + QPoint targetScreenPosition = m_sourceWidget->mapToGlobal(NormalizedPositionToWidgetPosition(lastCursorPosition)); + AzQtComponents::SetCursorPos(targetScreenPosition); + + // Even though we just set the cursor position, there are edge cases such as remote desktop that will leave + // the cursor position unchanged. For safety, we re-cache our last cursor position for delta generation. + QPoint actualWidgetPosition = m_sourceWidget->mapFromGlobal(QCursor::pos()); + m_cursorPosition->m_normalizedPosition = WidgetPositionToNormalizedPosition(actualWidgetPosition); + } } void QtEventToAzInputMapper::HandleKeyEvent(QKeyEvent* keyEvent) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.h index 6d95f3a4b0..6946a2c8e7 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Input/QtEventToAzInputManager.h @@ -47,6 +47,12 @@ namespace AzToolsFramework //! Sets whether or not this input mapper should be updating its input channels from Qt events. void SetEnabled(bool enabled); + //! Sets whether or not the cursor should be constrained to the source widget and invisible. + //! Internally, this will reset the cursor position after each move event to ensure movement + //! events don't allow the cursor to escape. This can be used for typical camera controls + //! like a dolly or rotation, where mouse movement is important but cursor location is not. + void SetCursorCaptureEnabled(bool enabled); + // QObject overrides... bool eventFilter(QObject* object, QEvent* event) override; @@ -106,6 +112,11 @@ namespace AzToolsFramework // Processes any pending mouse movement events, this allows mouse movement channels to close themselves. void ProcessPendingMouseEvents(); + // Converts a point in logical source widget space [0..m_sourceWidget->size()] to normalized [0..1] space. + AZ::Vector2 WidgetPositionToNormalizedPosition(QPoint position); + // Converts a point in normalized [0..1] space to logical source widget space [0..m_sourceWidget->size()]. + QPoint NormalizedPositionToWidgetPosition(AZ::Vector2 normalizedPosition); + // Handle mouse click events. void HandleMouseButtonEvent(QMouseEvent* mouseEvent); // Handle mouse move events. @@ -144,6 +155,8 @@ namespace AzToolsFramework bool m_mouseChannelsNeedUpdate = false; // Flags whether or not Qt events should currently be processed. bool m_enabled = true; + // Flags whether or not the cursor is being constrained to the source widget (for invisible mouse movement). + bool m_capturingCursor = false; // Our viewport-specific AZ devices. We control their internal input channel states. AZStd::unique_ptr m_mouseDevice; diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h index 4d3af0e878..5b25034de8 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Viewport/ViewportMessages.h @@ -276,11 +276,6 @@ namespace AzToolsFramework virtual void EndCursorCapture() = 0; //! Gets the most recent recorded cursor position in the viewport in screen space coordinates. virtual AzFramework::ScreenPoint ViewportCursorScreenPosition() = 0; - //! Gets the cursor position recorded prior to the most recent cursor position. - //! Note: The cursor may be captured by the viewport, in which case this may not correspond to the last result - //! from ViewportCursorScreenPosition. This method will always return the correct position to generate a mouse - //! position delta. - virtual AZStd::optional PreviousViewportCursorScreenPosition() = 0; //! Is mouse over viewport. virtual bool IsMouseOver() const = 0; diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h index d8171a83a1..99a3ea4840 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h @@ -109,7 +109,6 @@ namespace AtomToolsFramework void BeginCursorCapture() override; void EndCursorCapture() override; AzFramework::ScreenPoint ViewportCursorScreenPosition() override; - AZStd::optional PreviousViewportCursorScreenPosition() override; bool IsMouseOver() const override; // AzFramework::WindowRequestBus::Handler ... @@ -160,8 +159,6 @@ namespace AtomToolsFramework AZ::ScriptTimePoint m_time; // Whether the Viewport is currently hiding and capturing the cursor position. bool m_capturingCursor = false; - // The last known position of the mouse cursor, if one is available. - AZStd::optional m_lastCursorPosition; // The viewport settings (e.g. grid snapping, grid size) for this viewport. const AzToolsFramework::ViewportInteraction::ViewportSettings* m_viewportSettings = nullptr; // Maps our internal Qt events into AzFramework InputChannels for our ViewportControllerList. diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp index 6ab96bbebb..ff10b49483 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -234,18 +233,6 @@ namespace AtomToolsFramework void RenderViewportWidget::mouseMoveEvent(QMouseEvent* event) { m_mousePosition = event->localPos(); - - if (m_capturingCursor && m_lastCursorPosition.has_value()) - { - AzQtComponents::SetCursorPos(m_lastCursorPosition.value()); - // Even though we just set the cursor position, there are edge cases such as remote desktop that will leave - // the cursor position unchanged. For safety, we re-cache our last cursor position for delta generation. - m_lastCursorPosition = QCursor::pos(); - } - else - { - m_lastCursorPosition = event->globalPos(); - } } void RenderViewportWidget::SendWindowResizeEvent() @@ -420,13 +407,6 @@ namespace AtomToolsFramework return AzToolsFramework::ViewportInteraction::ScreenPointFromQPoint(m_mousePosition.toPoint()); } - AZStd::optional RenderViewportWidget::PreviousViewportCursorScreenPosition() - { - using AzToolsFramework::ViewportInteraction::ScreenPointFromQPoint; - return m_lastCursorPosition.has_value() ? ScreenPointFromQPoint(mapFromGlobal(m_lastCursorPosition.value())) - : AZStd::optional{}; - } - bool RenderViewportWidget::IsMouseOver() const { return m_mouseOver; @@ -434,24 +414,12 @@ namespace AtomToolsFramework void RenderViewportWidget::BeginCursorCapture() { - if (m_capturingCursor) - { - return; - } - - qApp->setOverrideCursor(Qt::BlankCursor); - m_capturingCursor = true; + m_inputChannelMapper->SetCursorCaptureEnabled(true); } void RenderViewportWidget::EndCursorCapture() { - if (!m_capturingCursor) - { - return; - } - - qApp->restoreOverrideCursor(); - m_capturingCursor = false; + m_inputChannelMapper->SetCursorCaptureEnabled(false); } void RenderViewportWidget::SetWindowTitle(const AZStd::string& title) From 3ea3d7a436255856ec8a4be0be62739c83aec72a Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Tue, 13 Jul 2021 23:52:52 -0700 Subject: [PATCH 31/53] Data integrity issue, keyframe times need to be ascending (#2130) * User provided animation resulted in a data integrity error. * The first track had 0.66 as max time while another had a keyframe more resulting in 0.69. * When updating the duration before fixing up the last keyframe for each of the tracks, the duration was returned early with 0.66 while there were other tracks having a keyframe more. * We're now crawling through all tracks to determine the maximum duration. * This results in a correct fixup of the last frame. Signed-off-by: Benjamin Jillich --- .../MotionData/NonUniformMotionData.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.cpp index f9e0911d51..5c530e35e3 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/MotionData/NonUniformMotionData.cpp @@ -412,25 +412,24 @@ namespace EMotionFX void NonUniformMotionData::UpdateDuration() { + m_duration = 0.0f; + for (const JointData& jointData : m_jointData) { if (!jointData.m_positionTrack.m_times.empty()) { - m_duration = jointData.m_positionTrack.m_times.back(); - return; + m_duration = AZ::GetMax(m_duration, jointData.m_positionTrack.m_times.back()); } if (!jointData.m_rotationTrack.m_times.empty()) { - m_duration = jointData.m_rotationTrack.m_times.back(); - return; + m_duration = AZ::GetMax(m_duration, jointData.m_rotationTrack.m_times.back()); } #ifndef EMFX_SCALE_DISABLED if (!jointData.m_scaleTrack.m_times.empty()) { - m_duration = jointData.m_scaleTrack.m_times.back(); - return; + m_duration = AZ::GetMax(m_duration, jointData.m_scaleTrack.m_times.back()); } #endif } @@ -439,8 +438,7 @@ namespace EMotionFX { if (!morphData.m_track.m_times.empty()) { - m_duration = morphData.m_track.m_times.back(); - return; + m_duration = AZ::GetMax(m_duration, morphData.m_track.m_times.back()); } } @@ -448,12 +446,9 @@ namespace EMotionFX { if (!floatData.m_track.m_times.empty()) { - m_duration = floatData.m_track.m_times.back(); - return; + m_duration = AZ::GetMax(m_duration, floatData.m_track.m_times.back()); } } - - m_duration = 0.0f; } void NonUniformMotionData::AllocateJointPositionSamples(size_t jointDataIndex, size_t numSamples) From 8f4ded8c643febdf1364860bfedd255a01309060 Mon Sep 17 00:00:00 2001 From: Chris Galvan Date: Wed, 14 Jul 2021 12:10:49 -0500 Subject: [PATCH 32/53] Use the proper undo sequence so that viewport camera changes are saved properly. Signed-off-by: Chris Galvan --- Code/Editor/EditorViewportWidget.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Code/Editor/EditorViewportWidget.cpp b/Code/Editor/EditorViewportWidget.cpp index 3f86260f8d..c2f16a84b1 100644 --- a/Code/Editor/EditorViewportWidget.cpp +++ b/Code/Editor/EditorViewportWidget.cpp @@ -1896,7 +1896,7 @@ void EditorViewportWidget::SetViewTM(const Matrix34& viewTM, bool bMoveOnly) if (m_pressedKeyState != KeyPressedState::PressedInPreviousFrame) { - CUndo undo("Move Camera"); + AzToolsFramework::ScopedUndoBatch undo("Move Camera"); if (bMoveOnly) { // specify eObjectUpdateFlags_UserInput so that an undo command gets logged @@ -1932,7 +1932,7 @@ void EditorViewportWidget::SetViewTM(const Matrix34& viewTM, bool bMoveOnly) if (m_pressedKeyState != KeyPressedState::PressedInPreviousFrame) { - CUndo undo("Move Camera"); + AzToolsFramework::ScopedUndoBatch undo("Move Camera"); if (bMoveOnly) { AZ::TransformBus::Event( @@ -1945,6 +1945,8 @@ void EditorViewportWidget::SetViewTM(const Matrix34& viewTM, bool bMoveOnly) m_viewEntityId, &AZ::TransformInterface::SetWorldTM, LYTransformToAZTransform(camMatrix)); } + + AzToolsFramework::ToolsApplicationRequestBus::Broadcast(&AzToolsFramework::ToolsApplicationRequests::AddDirtyEntity, m_viewEntityId); } else { From cd819062f9336f0ad313b4a7273f97b9d44059c1 Mon Sep 17 00:00:00 2001 From: AMZN-tpeng <82184807+AMZN-tpeng@users.noreply.github.com> Date: Wed, 14 Jul 2021 10:20:39 -0700 Subject: [PATCH 33/53] [ATOM][RHI][Vulkan][Android] - use bit conversion from enum to check for gpu query type support (#2141) ATOM-15742 Signed-off-by: Tony Peng Signed-off-by: Peng --- .../Atom/RPI/Code/Source/RPI.Public/GpuQuery/GpuQuerySystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/GpuQuery/GpuQuerySystem.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/GpuQuery/GpuQuerySystem.cpp index bf3107cfdf..5d621094ea 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/GpuQuery/GpuQuerySystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/GpuQuery/GpuQuerySystem.cpp @@ -116,7 +116,7 @@ namespace AZ { AZ_Assert(IsQueryTypeValid(queryType), "Provided QueryType is invalid"); - return static_cast(m_queryTypeSupport) & static_cast(queryType); + return static_cast(m_queryTypeSupport) & AZ_BIT(static_cast(queryType)); } RPI::QueryPool* GpuQuerySystem::GetQueryPoolByType(RHI::QueryType queryType) From d6d644501a26272adb3fddbf90ca5bfa733a5b48 Mon Sep 17 00:00:00 2001 From: AMZN-tpeng <82184807+AMZN-tpeng@users.noreply.github.com> Date: Wed, 14 Jul 2021 10:22:49 -0700 Subject: [PATCH 34/53] [ATOM][RHI][Vulkan][Android] - Fix sample count validation error for android. (#2145) ATOM-15755 Signed-off-by: Tony Peng Signed-off-by: Peng --- Gems/Atom/RHI/Vulkan/Code/Source/RHI/Image.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Image.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Image.cpp index 7586183b63..61149c19f7 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Image.cpp +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Image.cpp @@ -218,7 +218,8 @@ namespace AZ createInfo.extent = extent; createInfo.mipLevels = AZStd::min(descriptor.m_mipLevels, formatProps.maxMipLevels); createInfo.arrayLayers = AZStd::min(descriptor.m_arraySize, formatProps.maxArrayLayers); - createInfo.samples = static_cast(RHI::FilterBits(static_cast(ConvertSampleCount(descriptor.m_multisampleState.m_samples)), formatProps.sampleCounts)); + VkSampleCountFlagBits sampleCountFlagBits = static_cast(RHI::FilterBits(static_cast(ConvertSampleCount(descriptor.m_multisampleState.m_samples)), formatProps.sampleCounts)); + createInfo.samples = (static_cast(sampleCountFlagBits) > 0) ? sampleCountFlagBits : VK_SAMPLE_COUNT_1_BIT; createInfo.tiling = VK_IMAGE_TILING_OPTIMAL; createInfo.usage = GetImageUsageFlags(); createInfo.sharingMode = exclusiveOwnership ? VK_SHARING_MODE_EXCLUSIVE : VK_SHARING_MODE_CONCURRENT; From 8f706c09d64b8d000b19d9b5066b1a6d6485e37c Mon Sep 17 00:00:00 2001 From: amzn-sean <75276488+amzn-sean@users.noreply.github.com> Date: Wed, 14 Jul 2021 20:16:56 +0100 Subject: [PATCH 35/53] update sc that is used in physics tests to use the 'PhysicsSystemInterface' instead of 'System Interface' (#2162) Signed-off-by: amzn-sean <75276488+amzn-sean@users.noreply.github.com> --- .../onpostphysicsupdate.scriptcanvas | 4 ++-- .../C14195074_ScriptCanvas_PostUpdateEvent.scriptcanvas | 4 ++-- .../C14902097_ScriptCanvas_PreUpdateEvent.scriptcanvas | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/AutomatedTesting/Levels/Physics/C14902098_ScriptCanvas_PostPhysicsUpdate/onpostphysicsupdate.scriptcanvas b/AutomatedTesting/Levels/Physics/C14902098_ScriptCanvas_PostPhysicsUpdate/onpostphysicsupdate.scriptcanvas index f4ca23b882..10c40fbb9f 100644 --- a/AutomatedTesting/Levels/Physics/C14902098_ScriptCanvas_PostPhysicsUpdate/onpostphysicsupdate.scriptcanvas +++ b/AutomatedTesting/Levels/Physics/C14902098_ScriptCanvas_PostPhysicsUpdate/onpostphysicsupdate.scriptcanvas @@ -742,14 +742,14 @@ - + - + diff --git a/AutomatedTesting/ScriptCanvas/C14195074_ScriptCanvas_PostUpdateEvent.scriptcanvas b/AutomatedTesting/ScriptCanvas/C14195074_ScriptCanvas_PostUpdateEvent.scriptcanvas index b9f438a4f3..ffdac5dd8c 100644 --- a/AutomatedTesting/ScriptCanvas/C14195074_ScriptCanvas_PostUpdateEvent.scriptcanvas +++ b/AutomatedTesting/ScriptCanvas/C14195074_ScriptCanvas_PostUpdateEvent.scriptcanvas @@ -1045,14 +1045,14 @@ - + - + diff --git a/AutomatedTesting/ScriptCanvas/C14902097_ScriptCanvas_PreUpdateEvent.scriptcanvas b/AutomatedTesting/ScriptCanvas/C14902097_ScriptCanvas_PreUpdateEvent.scriptcanvas index 7db4f3a35c..4954eb4684 100644 --- a/AutomatedTesting/ScriptCanvas/C14902097_ScriptCanvas_PreUpdateEvent.scriptcanvas +++ b/AutomatedTesting/ScriptCanvas/C14902097_ScriptCanvas_PreUpdateEvent.scriptcanvas @@ -1085,14 +1085,14 @@ - + - + From ffcfa44b49825fe3305577f6635c72d09639ec4d Mon Sep 17 00:00:00 2001 From: jackalbe <23512001+jackalbe@users.noreply.github.com> Date: Wed, 14 Jul 2021 14:54:22 -0500 Subject: [PATCH 36/53] {LYN-4514} Engine updates to enable PAB for the Blast Gem (#2140) * {LYN-4514} Engine updates to enable PAB for the Blast Gem * Engine updates to enable Python Asset Building for the Blast Gem * added API to detect IsPythonActive() * ExportProductList behavior * scene manifest usage of generated assetinfo * updated ScriptProcessorRuleBehavior to handle OnPrepareForExport Tests: new tests for scene behavior via ExportProduct Signed-off-by: Jackson <23512001+jackalbe@users.noreply.github.com> * updated base on PR feedback added more comments for IsPythonActive() added a serializeContext for export product list Signed-off-by: Jackson <23512001+jackalbe@users.noreply.github.com> --- .../AzCore/AzCore/Math/MathReflection.cpp | 2 +- .../API/EditorPythonConsoleBus.h | 3 + .../Components/ExportingComponent.cpp | 8 + Code/Tools/SceneAPI/SceneCore/DllMain.cpp | 1 + .../SceneCore/Events/ExportProductList.cpp | 41 + .../SceneCore/Events/ExportProductList.h | 11 + .../Import/ManifestImportRequestHandler.cpp | 12 +- .../Tests/Containers/SceneBehaviorTests.cpp | 1269 +++++++++-------- .../Behaviors/ScriptProcessorRuleBehavior.cpp | 452 +++--- .../Behaviors/ScriptProcessorRuleBehavior.h | 74 +- .../Code/Source/PythonSystemComponent.cpp | 17 +- .../Code/Source/PythonSystemComponent.h | 1 + 12 files changed, 1053 insertions(+), 838 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Math/MathReflection.cpp b/Code/Framework/AzCore/AzCore/Math/MathReflection.cpp index 46717440d5..82e230d54a 100644 --- a/Code/Framework/AzCore/AzCore/Math/MathReflection.cpp +++ b/Code/Framework/AzCore/AzCore/Math/MathReflection.cpp @@ -116,7 +116,7 @@ namespace AZ { const char* uuidString = nullptr; unsigned int uuidStringLength = 0; - if (dc.ReadArg(0, uuidString) && dc.ReadValue(1, uuidStringLength)) + if (dc.ReadArg(0, uuidString) && dc.ReadArg(1, uuidStringLength)) { dc.PushResult(Uuid(uuidString, uuidStringLength)); } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorPythonConsoleBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorPythonConsoleBus.h index 51aecbd8e7..6dd6b0b448 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorPythonConsoleBus.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/API/EditorPythonConsoleBus.h @@ -63,6 +63,9 @@ namespace AzToolsFramework //! Signal the Python handler to stop virtual bool StopPython(bool silenceWarnings = false) = 0; + //! Query to determine if the Python VM has been initialized indicating an active state + virtual bool IsPythonActive() = 0; + //! Determines if the caller needs to wait for the Python VM to initialize (non-main thread only) virtual void WaitForInitialization() {} diff --git a/Code/Tools/SceneAPI/SceneCore/Components/ExportingComponent.cpp b/Code/Tools/SceneAPI/SceneCore/Components/ExportingComponent.cpp index 62daba1197..911f469b2f 100644 --- a/Code/Tools/SceneAPI/SceneCore/Components/ExportingComponent.cpp +++ b/Code/Tools/SceneAPI/SceneCore/Components/ExportingComponent.cpp @@ -7,6 +7,8 @@ #include #include +#include +#include namespace AZ { @@ -31,6 +33,12 @@ namespace AZ { serializeContext->Class()->Version(2); } + + AZ::BehaviorContext* behaviorContext = azrtti_cast(context); + if (behaviorContext) + { + Events::ExportProductList::Reflect(behaviorContext); + } } } // namespace SceneCore } // namespace SceneAPI diff --git a/Code/Tools/SceneAPI/SceneCore/DllMain.cpp b/Code/Tools/SceneAPI/SceneCore/DllMain.cpp index 7874ada7be..ac3c307b6c 100644 --- a/Code/Tools/SceneAPI/SceneCore/DllMain.cpp +++ b/Code/Tools/SceneAPI/SceneCore/DllMain.cpp @@ -211,6 +211,7 @@ namespace AZ AZ::SceneAPI::Containers::SceneGraph::Reflect(context); AZ::SceneAPI::Containers::SceneManifest::Reflect(context); AZ::SceneAPI::Containers::RuleContainer::Reflect(context); + AZ::SceneAPI::SceneCore::ExportingComponent::Reflect(context); } void Activate() diff --git a/Code/Tools/SceneAPI/SceneCore/Events/ExportProductList.cpp b/Code/Tools/SceneAPI/SceneCore/Events/ExportProductList.cpp index c3a9abcbd2..798978024e 100644 --- a/Code/Tools/SceneAPI/SceneCore/Events/ExportProductList.cpp +++ b/Code/Tools/SceneAPI/SceneCore/Events/ExportProductList.cpp @@ -6,6 +6,8 @@ */ #include +#include +#include namespace AZ { @@ -49,6 +51,45 @@ namespace AZ return *this; } + void ExportProductList::Reflect(ReflectContext* context) + { + if (auto* serializeContext = azrtti_cast(context)) + { + serializeContext->Class()->Version(1); + serializeContext->Class()->Version(1); + } + + if (auto* behaviorContext = azrtti_cast(context)) + { + behaviorContext->Class("ExportProduct") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) + ->Attribute(AZ::Script::Attributes::Module, "scene") + ->Property("filename", BehaviorValueProperty(&ExportProduct::m_filename)) + ->Property("sourceId", BehaviorValueProperty(&ExportProduct::m_id)) + ->Property("assetType", BehaviorValueProperty(&ExportProduct::m_assetType)) + ->Property("productDependencies", BehaviorValueProperty(&ExportProduct::m_productDependencies)) + ->Property("subId", + [](ExportProduct* self) { return self->m_subId.has_value() ? self->m_subId.value() : 0; }, + [](ExportProduct* self, u32 subId) { self->m_subId = AZStd::optional(subId); }); + + behaviorContext->Class("ExportProductList") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) + ->Attribute(AZ::Script::Attributes::Module, "scene") + ->Method("AddProduct", [](ExportProductList& self, ExportProduct& product) + { + self.AddProduct( + product.m_filename, + product.m_id, + product.m_assetType, + product.m_lod, + product.m_subId, + product.m_dependencyFlags); + }) + ->Method("GetProducts", &ExportProductList::GetProducts) + ->Method("AddDependencyToProduct", &ExportProductList::AddDependencyToProduct); + } + } + ExportProduct& ExportProductList::AddProduct(const AZStd::string& filename, Uuid id, Data::AssetType assetType, AZStd::optional lod, AZStd::optional subId, Data::ProductDependencyInfo::ProductDependencyFlags dependencyFlags) { diff --git a/Code/Tools/SceneAPI/SceneCore/Events/ExportProductList.h b/Code/Tools/SceneAPI/SceneCore/Events/ExportProductList.h index 38deea3f9f..a99303e08b 100644 --- a/Code/Tools/SceneAPI/SceneCore/Events/ExportProductList.h +++ b/Code/Tools/SceneAPI/SceneCore/Events/ExportProductList.h @@ -14,6 +14,8 @@ namespace AZ { + class ReflectContext; + namespace SceneAPI { namespace Events @@ -24,6 +26,7 @@ namespace AZ Data::ProductDependencyInfo::ProductDependencyFlags dependencyFlags = Data::ProductDependencyInfo::CreateFlags(Data::AssetLoadBehavior::NoLoad)); SCENE_CORE_API ExportProduct(AZStd::string&& filename, Uuid id, Data::AssetType assetType, AZStd::optional lod, AZStd::optional subId, Data::ProductDependencyInfo::ProductDependencyFlags dependencyFlags = Data::ProductDependencyInfo::CreateFlags(Data::AssetLoadBehavior::NoLoad)); + ExportProduct() = default; ExportProduct(const ExportProduct& rhs) = default; SCENE_CORE_API ExportProduct(ExportProduct&& rhs); @@ -54,6 +57,8 @@ namespace AZ class ExportProductList { public: + static void Reflect(ReflectContext* context); + SCENE_CORE_API ExportProduct& AddProduct(const AZStd::string& filename, Uuid id, Data::AssetType assetType, AZStd::optional lod, AZStd::optional subId, Data::ProductDependencyInfo::ProductDependencyFlags dependencyFlags = Data::ProductDependencyInfo::CreateFlags(Data::AssetLoadBehavior::NoLoad)); SCENE_CORE_API ExportProduct& AddProduct(AZStd::string&& filename, Uuid id, Data::AssetType assetType, AZStd::optional lod, AZStd::optional subId, @@ -69,3 +74,9 @@ namespace AZ } // namespace Events } // namespace SceneAPI } // namespace AZ + +namespace AZ +{ + AZ_TYPE_INFO_SPECIALIZE(SceneAPI::Events::ExportProduct, "{6054EDCB-4C04-4D96-BF26-704999FFB725}"); + AZ_TYPE_INFO_SPECIALIZE(SceneAPI::Events::ExportProductList, "{1C76A51F-431B-4987-B653-CFCC940D0D0F}"); +} diff --git a/Code/Tools/SceneAPI/SceneCore/Import/ManifestImportRequestHandler.cpp b/Code/Tools/SceneAPI/SceneCore/Import/ManifestImportRequestHandler.cpp index a4b002db7d..073f357ee6 100644 --- a/Code/Tools/SceneAPI/SceneCore/Import/ManifestImportRequestHandler.cpp +++ b/Code/Tools/SceneAPI/SceneCore/Import/ManifestImportRequestHandler.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -75,15 +76,16 @@ namespace AZ filename += s_extension; filename += s_generated; - AZStd::string altManifestPath = path; + AZStd::string altManifestFolder = path; AzFramework::ApplicationRequests::Bus::Broadcast( - &AzFramework::ApplicationRequests::Bus::Events::MakePathRootRelative, - altManifestPath); + &AzFramework::ApplicationRequests::Bus::Events::MakePathRelative, + altManifestFolder, + AZ::Utils::GetProjectPath().c_str()); - AZ::StringFunc::Path::GetFolderPath(altManifestPath.c_str(), altManifestPath); + AZ::StringFunc::Path::GetFolderPath(altManifestFolder.c_str(), altManifestFolder); AZStd::string generatedAssetInfoPath; - AZ::StringFunc::Path::Join(assetCacheRoot.c_str(), altManifestPath.c_str(), generatedAssetInfoPath); + AZ::StringFunc::Path::Join(assetCacheRoot.c_str(), altManifestFolder.c_str(), generatedAssetInfoPath); AZ::StringFunc::Path::ConstructFull(generatedAssetInfoPath.c_str(), filename.c_str(), generatedAssetInfoPath); if (!AZ::IO::FileIOBase::GetInstance()->Exists(generatedAssetInfoPath.c_str())) diff --git a/Code/Tools/SceneAPI/SceneCore/Tests/Containers/SceneBehaviorTests.cpp b/Code/Tools/SceneAPI/SceneCore/Tests/Containers/SceneBehaviorTests.cpp index e1c72bc8b4..4e08181b83 100644 --- a/Code/Tools/SceneAPI/SceneCore/Tests/Containers/SceneBehaviorTests.cpp +++ b/Code/Tools/SceneAPI/SceneCore/Tests/Containers/SceneBehaviorTests.cpp @@ -28,710 +28,731 @@ extern "C" AZ_DLL_EXPORT void ReflectBehavior(AZ::BehaviorContext* context); // the DLL entry point for SceneCore to reflect its serialize context extern "C" AZ_DLL_EXPORT void ReflectTypes(AZ::SerializeContext* context); -namespace AZ +namespace AZ::SceneAPI::Containers { - namespace SceneAPI + class MockManifestRule : public DataTypes::IManifestObject { - namespace Containers + public: + AZ_RTTI(MockManifestRule, "{D6F96B48-4E6F-4EE8-A5A3-959B76F90DA8}", IManifestObject); + AZ_CLASS_ALLOCATOR(MockManifestRule, AZ::SystemAllocator, 0); + + MockManifestRule() = default; + + MockManifestRule(double value) + : m_value(value) + { + } + + double GetValue() const + { + return m_value; + } + + void SetValue(double value) { - class MockManifestRule : public DataTypes::IManifestObject + m_value = value; + } + + static void Reflect(AZ::ReflectContext* context) + { + AZ::SerializeContext* serializeContext = azrtti_cast(context); + if (serializeContext) { - public: - AZ_RTTI(MockManifestRule, "{D6F96B48-4E6F-4EE8-A5A3-959B76F90DA8}", IManifestObject); - AZ_CLASS_ALLOCATOR(MockManifestRule, AZ::SystemAllocator, 0); + serializeContext->Class() + ->Version(1) + ->Field("value", &MockManifestRule::m_value); + } + } - MockManifestRule() = default; + private: + double m_value = 0.0; + }; - MockManifestRule(double value) - : m_value(value) - { - } + struct MockBuilder final + { + AZ_TYPE_INFO(MockBuilder, "{ECF0FB2C-E5C0-4B89-993C-8511A7EF6894}"); - double GetValue() const - { - return m_value; - } + AZStd::unique_ptr m_scene; - void SetValue(double value) - { - m_value = value; - } + MockBuilder() + { + m_scene = AZStd::make_unique("unit_scene"); + } - static void Reflect(AZ::ReflectContext* context) - { - AZ::SerializeContext* serializeContext = azrtti_cast(context); - if (serializeContext) - { - serializeContext->Class() - ->Version(1) - ->Field("value", &MockManifestRule::m_value); - } - } + ~MockBuilder() + { + m_scene.reset(); + } - private: - double m_value = 0.0; - }; + void BuildSceneGraph() + { + m_scene->SetManifestFilename("manifest_filename"); + m_scene->SetSource("unit_source_filename", azrtti_typeid()); + + auto& graph = m_scene->GetGraph(); + + /*----------------------------\ + | Root | + | / \ | + | | | | + | A B | + | | /|\ | + | C I J K | + | / | \ \ | + | D E F L | + | / \ | + | G H | + \----------------------------*/ + + //Build up the graph + const auto indexA = graph.AddChild(graph.GetRoot(), "A", AZStd::make_shared(1)); + const auto indexC = graph.AddChild(indexA, "C", AZStd::make_shared(3)); + const auto indexE = graph.AddChild(indexC, "E", AZStd::make_shared(4)); + graph.AddChild(indexC, "D", AZStd::make_shared(5)); + graph.AddChild(indexC, "F", AZStd::make_shared(6)); + graph.AddChild(indexE, "G", AZStd::make_shared(7)); + graph.AddChild(indexE, "H", AZStd::make_shared(8)); + const auto indexB = graph.AddChild(graph.GetRoot(), "B", AZStd::make_shared(2)); + const auto indexK = graph.AddChild(indexB, "K", AZStd::make_shared(2)); + graph.AddChild(indexB, "I", AZStd::make_shared(9)); + graph.AddChild(indexB, "J", AZStd::make_shared(10)); + graph.AddChild(indexK, "L", AZStd::make_shared(12)); + + m_scene->GetManifest().AddEntry(AZStd::make_shared(0.1)); + m_scene->GetManifest().AddEntry(AZStd::make_shared(2.3)); + m_scene->GetManifest().AddEntry(AZStd::make_shared(4.5)); + } - struct MockBuilder final + static void Reflect(ReflectContext* context) + { + BehaviorContext* behaviorContext = azrtti_cast(context); + if (behaviorContext) { - AZ_TYPE_INFO(MockBuilder, "{ECF0FB2C-E5C0-4B89-993C-8511A7EF6894}"); + behaviorContext->Class() + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) + ->Attribute(AZ::Script::Attributes::Module, "scene") + ->Method("BuildSceneGraph", [](MockBuilder& self) + { + return self.BuildSceneGraph(); + }) + ->Method("GetScene", [](MockBuilder& self) + { + return self.m_scene.get(); + }); + } + } + }; - AZStd::unique_ptr m_scene; + class SceneGraphBehaviorTest + : public ::testing::Test + { + public: + void SetUp() override + { + m_behaviorContext = AZStd::make_unique(); + ReflectBehavior(m_behaviorContext.get()); + } - MockBuilder() - { - m_scene = AZStd::make_unique("unit_scene"); - } + void TearDown() override + { + m_behaviorContext.reset(); + } - ~MockBuilder() - { - m_scene.reset(); - } + AZ::BehaviorClass* GetBehaviorClass(const AZ::TypeId& behaviorClassType) + { + auto entry = m_behaviorContext->m_typeToClassMap.find(behaviorClassType); + return (entry != m_behaviorContext->m_typeToClassMap.end()) ? entry->second : nullptr; + } - void BuildSceneGraph() - { - m_scene->SetManifestFilename("manifest_filename"); - m_scene->SetSource("unit_source_filename", azrtti_typeid()); - - auto& graph = m_scene->GetGraph(); - - /*----------------------------\ - | Root | - | / \ | - | | | | - | A B | - | | /|\ | - | C I J K | - | / | \ \ | - | D E F L | - | / \ | - | G H | - \----------------------------*/ - - //Build up the graph - const auto indexA = graph.AddChild(graph.GetRoot(), "A", AZStd::make_shared(1)); - const auto indexC = graph.AddChild(indexA, "C", AZStd::make_shared(3)); - const auto indexE = graph.AddChild(indexC, "E", AZStd::make_shared(4)); - graph.AddChild(indexC, "D", AZStd::make_shared(5)); - graph.AddChild(indexC, "F", AZStd::make_shared(6)); - graph.AddChild(indexE, "G", AZStd::make_shared(7)); - graph.AddChild(indexE, "H", AZStd::make_shared(8)); - const auto indexB = graph.AddChild(graph.GetRoot(), "B", AZStd::make_shared(2)); - const auto indexK = graph.AddChild(indexB, "K", AZStd::make_shared(2)); - graph.AddChild(indexB, "I", AZStd::make_shared(9)); - graph.AddChild(indexB, "J", AZStd::make_shared(10)); - graph.AddChild(indexK, "L", AZStd::make_shared(12)); - - m_scene->GetManifest().AddEntry(AZStd::make_shared(0.1)); - m_scene->GetManifest().AddEntry(AZStd::make_shared(2.3)); - m_scene->GetManifest().AddEntry(AZStd::make_shared(4.5)); - } + AZ::BehaviorProperty* GetBehaviorProperty(AZ::BehaviorClass& behaviorClass, AZStd::string_view propertyName) + { + auto entry = behaviorClass.m_properties.find(propertyName); + return (entry != behaviorClass.m_properties.end()) ? entry->second : nullptr; + } - static void Reflect(ReflectContext* context) - { - BehaviorContext* behaviorContext = azrtti_cast(context); - if (behaviorContext) - { - behaviorContext->Class() - ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) - ->Attribute(AZ::Script::Attributes::Module, "scene") - ->Method("BuildSceneGraph", [](MockBuilder& self) - { - return self.BuildSceneGraph(); - }) - ->Method("GetScene", [](MockBuilder& self) - { - return self.m_scene.get(); - }); - } - } - }; + bool HasBehaviorClass(const AZ::TypeId& behaviorClassType) + { + return GetBehaviorClass(behaviorClassType) != nullptr; + } - class SceneGraphBehaviorTest - : public ::testing::Test + bool HasProperty(AZ::BehaviorClass& behaviorClass, AZStd::string_view propertyName, const AZ::TypeId& propertyClassType) + { + AZ::BehaviorProperty* behaviorProperty = GetBehaviorProperty(behaviorClass, propertyName); + if (behaviorProperty) { - public: - void SetUp() override - { - m_behaviorContext = AZStd::make_unique(); - ReflectBehavior(m_behaviorContext.get()); - } + return behaviorProperty->m_getter->GetResult()->m_typeId == propertyClassType; + } + return false; + } - void TearDown() override - { - m_behaviorContext.reset(); - } + using ArgList = AZStd::vector; - AZ::BehaviorClass* GetBehaviorClass(const AZ::TypeId& behaviorClassType) - { - auto entry = m_behaviorContext->m_typeToClassMap.find(behaviorClassType); - return (entry != m_behaviorContext->m_typeToClassMap.end()) ? entry->second : nullptr; - } + bool HasMethodWithInput(AZ::BehaviorClass& behaviorClass, AZStd::string_view methodName, const ArgList& input) + { + auto entry = behaviorClass.m_methods.find(methodName); + if (entry == behaviorClass.m_methods.end()) + { + return false; + } + AZ::BehaviorMethod* method = entry->second; - AZ::BehaviorProperty* GetBehaviorProperty(AZ::BehaviorClass& behaviorClass, AZStd::string_view propertyName) - { - auto entry = behaviorClass.m_properties.find(propertyName); - return (entry != behaviorClass.m_properties.end()) ? entry->second : nullptr; - } + const size_t methodArgsCount = method->IsMember() ? method->GetNumArguments() - 1 : method->GetNumArguments(); + if (input.size() != methodArgsCount) + { + return false; + } - bool HasBehaviorClass(const AZ::TypeId& behaviorClassType) + for (size_t argIndex = 0; argIndex < input.size(); ++argIndex) + { + const size_t thisPointerOffset = method->IsMember() ? 1 : 0; + const auto argType = method->GetArgument(argIndex + thisPointerOffset)->m_typeId; + const auto inputType = input[argIndex]; + if (inputType != argType) { - return GetBehaviorClass(behaviorClassType) != nullptr; + return false; } + } + return true; + } - bool HasProperty(AZ::BehaviorClass& behaviorClass, AZStd::string_view propertyName, const AZ::TypeId& propertyClassType) + bool HasMethodWithOutput(AZ::BehaviorClass& behaviorClass, AZStd::string_view methodName, const AZ::TypeId& output, const ArgList& input) + { + auto entry = behaviorClass.m_methods.find(methodName); + if (entry == behaviorClass.m_methods.end()) + { + return false; + } + AZ::BehaviorMethod* method = entry->second; + if (method->HasResult()) + { + if (method->GetResult()->m_typeId != output) { - AZ::BehaviorProperty* behaviorProperty = GetBehaviorProperty(behaviorClass, propertyName); - if (behaviorProperty) - { - return behaviorProperty->m_getter->GetResult()->m_typeId == propertyClassType; - } return false; } + } + else + { + return false; + } + return HasMethodWithInput(behaviorClass, methodName, input); + } - using ArgList = AZStd::vector; + AZStd::unique_ptr m_behaviorContext; + }; - bool HasMethodWithInput(AZ::BehaviorClass& behaviorClass, AZStd::string_view methodName, const ArgList& input) - { - auto entry = behaviorClass.m_methods.find(methodName); - if (entry == behaviorClass.m_methods.end()) - { - return false; - } - AZ::BehaviorMethod* method = entry->second; + TEST_F(SceneGraphBehaviorTest, SceneClass_BehaviorContext_Exists) + { + EXPECT_TRUE(HasBehaviorClass(azrtti_typeid())); + } - const size_t methodArgsCount = method->IsMember() ? method->GetNumArguments() - 1 : method->GetNumArguments(); - if (input.size() != methodArgsCount) - { - return false; - } + TEST_F(SceneGraphBehaviorTest, SceneClass_BehaviorContext_HasExpectedProperties) + { + AZ::BehaviorClass* behaviorClass = GetBehaviorClass(azrtti_typeid()); + ASSERT_NE(nullptr, behaviorClass); + EXPECT_TRUE(HasProperty(*behaviorClass, "name", azrtti_typeid())); + EXPECT_TRUE(HasProperty(*behaviorClass, "manifestFilename", azrtti_typeid())); + EXPECT_TRUE(HasProperty(*behaviorClass, "sourceFilename", azrtti_typeid())); + EXPECT_TRUE(HasProperty(*behaviorClass, "sourceGuid", azrtti_typeid())); + EXPECT_TRUE(HasProperty(*behaviorClass, "graph", azrtti_typeid())); + EXPECT_TRUE(HasProperty(*behaviorClass, "manifest", azrtti_typeid())); + } - for (size_t argIndex = 0; argIndex < input.size(); ++argIndex) - { - const size_t thisPointerOffset = method->IsMember() ? 1 : 0; - const auto argType = method->GetArgument(argIndex + thisPointerOffset)->m_typeId; - const auto inputType = input[argIndex]; - if (inputType != argType) - { - return false; - } - } - return true; - } + TEST_F(SceneGraphBehaviorTest, SceneGraphClass_BehaviorContext_Exists) + { + EXPECT_TRUE(HasBehaviorClass(azrtti_typeid())); + EXPECT_TRUE(HasBehaviorClass(azrtti_typeid())); + EXPECT_TRUE(HasBehaviorClass(azrtti_typeid())); + } - bool HasMethodWithOutput(AZ::BehaviorClass& behaviorClass, AZStd::string_view methodName, const AZ::TypeId& output, const ArgList& input) - { - auto entry = behaviorClass.m_methods.find(methodName); - if (entry == behaviorClass.m_methods.end()) - { - return false; - } - AZ::BehaviorMethod* method = entry->second; - if (method->HasResult()) - { - if (method->GetResult()->m_typeId != output) - { - return false; - } - } - else - { - return false; - } - return HasMethodWithInput(behaviorClass, methodName, input); - } + TEST_F(SceneGraphBehaviorTest, SceneGraphClass_BehaviorContext_HasExpectedProperties) + { + using namespace AZ::SceneAPI::Containers; + + AZ::BehaviorClass* behaviorClass = GetBehaviorClass(azrtti_typeid()); + ASSERT_NE(nullptr, behaviorClass); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetNodeName", azrtti_typeid(), { azrtti_typeid() })); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetRoot", azrtti_typeid(), {})); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "HasNodeContent", azrtti_typeid(), { azrtti_typeid() })); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "HasNodeSibling", azrtti_typeid(), { azrtti_typeid() })); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "HasNodeChild", azrtti_typeid(), { azrtti_typeid() })); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "HasNodeParent", azrtti_typeid(), { azrtti_typeid() })); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "IsNodeEndPoint", azrtti_typeid(), { azrtti_typeid() })); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetNodeCount", azrtti_typeid(), {})); + EXPECT_TRUE(HasMethodWithOutput( + *behaviorClass, + "GetNodeParent", + azrtti_typeid(), + { azrtti_typeid(), azrtti_typeid() } + )); + EXPECT_TRUE(HasMethodWithOutput( + *behaviorClass, + "GetNodeSibling", + azrtti_typeid(), + { azrtti_typeid(), azrtti_typeid() } + )); + EXPECT_TRUE(HasMethodWithOutput( + *behaviorClass, + "GetNodeChild", + azrtti_typeid(), + { azrtti_typeid(), azrtti_typeid() } + )); + EXPECT_TRUE(HasMethodWithOutput( + *behaviorClass, + "FindWithPath", + azrtti_typeid(), + { azrtti_typeid(), azrtti_typeid() } + )); + EXPECT_TRUE(HasMethodWithOutput( + *behaviorClass, + "FindWithRootAndPath", + azrtti_typeid(), + { azrtti_typeid(), azrtti_typeid(), azrtti_typeid() } + )); + } - AZStd::unique_ptr m_behaviorContext; - }; + TEST_F(SceneGraphBehaviorTest, SceneGraphNodeIndexClass_BehaviorContext_HasExpectedProperties) + { + using namespace AZ::SceneAPI::Containers; + + AZ::BehaviorClass* behaviorClass = GetBehaviorClass(azrtti_typeid()); + ASSERT_NE(nullptr, behaviorClass); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "AsNumber", azrtti_typeid(), {})); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "Distance", azrtti_typeid(), { azrtti_typeid() })); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "IsValid", azrtti_typeid(), {})); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "Equal", azrtti_typeid(), { azrtti_typeid() })); + } - TEST_F(SceneGraphBehaviorTest, SceneClass_BehaviorContext_Exists) - { - EXPECT_TRUE(HasBehaviorClass(azrtti_typeid())); - } + TEST_F(SceneGraphBehaviorTest, SceneGraphNameClass_BehaviorContext_HasExpectedProperties) + { + using namespace AZ::SceneAPI::Containers; - TEST_F(SceneGraphBehaviorTest, SceneClass_BehaviorContext_HasExpectedProperties) - { - AZ::BehaviorClass* behaviorClass = GetBehaviorClass(azrtti_typeid()); - ASSERT_NE(nullptr, behaviorClass); - EXPECT_TRUE(HasProperty(*behaviorClass, "name", azrtti_typeid())); - EXPECT_TRUE(HasProperty(*behaviorClass, "manifestFilename", azrtti_typeid())); - EXPECT_TRUE(HasProperty(*behaviorClass, "sourceFilename", azrtti_typeid())); - EXPECT_TRUE(HasProperty(*behaviorClass, "sourceGuid", azrtti_typeid())); - EXPECT_TRUE(HasProperty(*behaviorClass, "graph", azrtti_typeid())); - EXPECT_TRUE(HasProperty(*behaviorClass, "manifest", azrtti_typeid())); - } + AZ::BehaviorClass* behaviorClass = GetBehaviorClass(azrtti_typeid()); + ASSERT_NE(nullptr, behaviorClass); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetPath", azrtti_typeid(), {})); + EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetName", azrtti_typeid(), {})); + } - TEST_F(SceneGraphBehaviorTest, SceneGraphClass_BehaviorContext_Exists) - { - EXPECT_TRUE(HasBehaviorClass(azrtti_typeid())); - EXPECT_TRUE(HasBehaviorClass(azrtti_typeid())); - EXPECT_TRUE(HasBehaviorClass(azrtti_typeid())); - } + class MockSceneComponentApplication + : public AZ::ComponentApplicationBus::Handler + { + public: + MockSceneComponentApplication() + { + AZ::ComponentApplicationBus::Handler::BusConnect(); + AZ::Interface::Register(this); + } - TEST_F(SceneGraphBehaviorTest, SceneGraphClass_BehaviorContext_HasExpectedProperties) - { - using namespace AZ::SceneAPI::Containers; - - AZ::BehaviorClass* behaviorClass = GetBehaviorClass(azrtti_typeid()); - ASSERT_NE(nullptr, behaviorClass); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetNodeName", azrtti_typeid(), { azrtti_typeid() })); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetRoot", azrtti_typeid(), {})); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "HasNodeContent", azrtti_typeid(), { azrtti_typeid() })); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "HasNodeSibling", azrtti_typeid(), { azrtti_typeid() })); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "HasNodeChild", azrtti_typeid(), { azrtti_typeid() })); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "HasNodeParent", azrtti_typeid(), { azrtti_typeid() })); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "IsNodeEndPoint", azrtti_typeid(), { azrtti_typeid() })); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetNodeCount", azrtti_typeid(), {})); - EXPECT_TRUE(HasMethodWithOutput( - *behaviorClass, - "GetNodeParent", - azrtti_typeid(), - { azrtti_typeid(), azrtti_typeid() } - )); - EXPECT_TRUE(HasMethodWithOutput( - *behaviorClass, - "GetNodeSibling", - azrtti_typeid(), - { azrtti_typeid(), azrtti_typeid() } - )); - EXPECT_TRUE(HasMethodWithOutput( - *behaviorClass, - "GetNodeChild", - azrtti_typeid(), - { azrtti_typeid(), azrtti_typeid() } - )); - EXPECT_TRUE(HasMethodWithOutput( - *behaviorClass, - "FindWithPath", - azrtti_typeid(), - { azrtti_typeid(), azrtti_typeid() } - )); - EXPECT_TRUE(HasMethodWithOutput( - *behaviorClass, - "FindWithRootAndPath", - azrtti_typeid(), - { azrtti_typeid(), azrtti_typeid(), azrtti_typeid() } - )); - } + ~MockSceneComponentApplication() + { + AZ::Interface::Unregister(this); + AZ::ComponentApplicationBus::Handler::BusDisconnect(); + } - TEST_F(SceneGraphBehaviorTest, SceneGraphNodeIndexClass_BehaviorContext_HasExpectedProperties) - { - using namespace AZ::SceneAPI::Containers; - - AZ::BehaviorClass* behaviorClass = GetBehaviorClass(azrtti_typeid()); - ASSERT_NE(nullptr, behaviorClass); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "AsNumber", azrtti_typeid(), {})); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "Distance", azrtti_typeid(), { azrtti_typeid() })); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "IsValid", azrtti_typeid(), {})); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "Equal", azrtti_typeid(), { azrtti_typeid() })); - } + MOCK_METHOD1(FindEntity, AZ::Entity* (const AZ::EntityId&)); + MOCK_METHOD1(AddEntity, bool(AZ::Entity*)); + MOCK_METHOD0(Destroy, void()); + MOCK_METHOD1(RegisterComponentDescriptor, void(const AZ::ComponentDescriptor*)); + MOCK_METHOD1(UnregisterComponentDescriptor, void(const AZ::ComponentDescriptor*)); + MOCK_METHOD1(RegisterEntityAddedEventHandler, void(AZ::EntityAddedEvent::Handler&)); + MOCK_METHOD1(RegisterEntityRemovedEventHandler, void(AZ::EntityRemovedEvent::Handler&)); + MOCK_METHOD1(RegisterEntityActivatedEventHandler, void(AZ::EntityActivatedEvent::Handler&)); + MOCK_METHOD1(RegisterEntityDeactivatedEventHandler, void(AZ::EntityDeactivatedEvent::Handler&)); + MOCK_METHOD1(SignalEntityActivated, void(AZ::Entity*)); + MOCK_METHOD1(SignalEntityDeactivated, void(AZ::Entity*)); + MOCK_METHOD1(RemoveEntity, bool(AZ::Entity*)); + MOCK_METHOD1(DeleteEntity, bool(const AZ::EntityId&)); + MOCK_METHOD1(GetEntityName, AZStd::string(const AZ::EntityId&)); + MOCK_METHOD1(EnumerateEntities, void(const ComponentApplicationRequests::EntityCallback&)); + MOCK_METHOD0(GetApplication, AZ::ComponentApplication* ()); + MOCK_METHOD0(GetSerializeContext, AZ::SerializeContext* ()); + MOCK_METHOD0(GetJsonRegistrationContext, AZ::JsonRegistrationContext* ()); + MOCK_METHOD0(GetBehaviorContext, AZ::BehaviorContext* ()); + MOCK_CONST_METHOD0(GetAppRoot, const char*()); + MOCK_CONST_METHOD0(GetEngineRoot, const char*()); + MOCK_CONST_METHOD0(GetExecutableFolder, const char* ()); + MOCK_METHOD0(GetDrillerManager, AZ::Debug::DrillerManager* ()); + MOCK_CONST_METHOD1(QueryApplicationType, void(AZ::ApplicationTypeQuery&)); + }; + + class MockEditorPythonConsoleInterface final + : public AzToolsFramework::EditorPythonConsoleInterface + { + public: + MockEditorPythonConsoleInterface() + { + AZ::Interface::Register(this); + } - TEST_F(SceneGraphBehaviorTest, SceneGraphNameClass_BehaviorContext_HasExpectedProperties) - { - using namespace AZ::SceneAPI::Containers; + ~MockEditorPythonConsoleInterface() + { + AZ::Interface::Unregister(this); + } - AZ::BehaviorClass* behaviorClass = GetBehaviorClass(azrtti_typeid()); - ASSERT_NE(nullptr, behaviorClass); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetPath", azrtti_typeid(), {})); - EXPECT_TRUE(HasMethodWithOutput(*behaviorClass, "GetName", azrtti_typeid(), {})); - } + MOCK_CONST_METHOD1(GetModuleList, void(AZStd::vector&)); + MOCK_CONST_METHOD1(GetGlobalFunctionList, void(GlobalFunctionCollection&)); + MOCK_METHOD1(FetchPythonTypeName, AZStd::string(const AZ::BehaviorParameter&)); + }; - class MockSceneComponentApplication - : public AZ::ComponentApplicationBus::Handler - { - public: - MockSceneComponentApplication() - { - AZ::ComponentApplicationBus::Handler::BusConnect(); - AZ::Interface::Register(this); - } + // + // SceneGraphBehaviorScriptTest + // + class SceneGraphBehaviorScriptTest + : public UnitTest::AllocatorsFixture + { + public: + AZStd::unique_ptr m_componentApplication; + AZStd::unique_ptr m_editorPythonConsoleInterface; + AZStd::unique_ptr m_scriptContext; + AZStd::unique_ptr m_behaviorContext; + AZStd::unique_ptr m_serializeContext; + + static void TestExpectTrue(bool value) + { + EXPECT_TRUE(value); + } - ~MockSceneComponentApplication() - { - AZ::Interface::Unregister(this); - AZ::ComponentApplicationBus::Handler::BusDisconnect(); - } + static void TestExpectEquals(AZ::s64 lhs, AZ::s64 rhs) + { + EXPECT_EQ(lhs, rhs); + } - MOCK_METHOD1(FindEntity, AZ::Entity* (const AZ::EntityId&)); - MOCK_METHOD1(AddEntity, bool(AZ::Entity*)); - MOCK_METHOD0(Destroy, void()); - MOCK_METHOD1(RegisterComponentDescriptor, void(const AZ::ComponentDescriptor*)); - MOCK_METHOD1(UnregisterComponentDescriptor, void(const AZ::ComponentDescriptor*)); - MOCK_METHOD1(RegisterEntityAddedEventHandler, void(AZ::EntityAddedEvent::Handler&)); - MOCK_METHOD1(RegisterEntityRemovedEventHandler, void(AZ::EntityRemovedEvent::Handler&)); - MOCK_METHOD1(RegisterEntityActivatedEventHandler, void(AZ::EntityActivatedEvent::Handler&)); - MOCK_METHOD1(RegisterEntityDeactivatedEventHandler, void(AZ::EntityDeactivatedEvent::Handler&)); - MOCK_METHOD1(SignalEntityActivated, void(AZ::Entity*)); - MOCK_METHOD1(SignalEntityDeactivated, void(AZ::Entity*)); - MOCK_METHOD1(RemoveEntity, bool(AZ::Entity*)); - MOCK_METHOD1(DeleteEntity, bool(const AZ::EntityId&)); - MOCK_METHOD1(GetEntityName, AZStd::string(const AZ::EntityId&)); - MOCK_METHOD1(EnumerateEntities, void(const ComponentApplicationRequests::EntityCallback&)); - MOCK_METHOD0(GetApplication, AZ::ComponentApplication* ()); - MOCK_METHOD0(GetSerializeContext, AZ::SerializeContext* ()); - MOCK_METHOD0(GetJsonRegistrationContext, AZ::JsonRegistrationContext* ()); - MOCK_METHOD0(GetBehaviorContext, AZ::BehaviorContext* ()); - MOCK_CONST_METHOD0(GetAppRoot, const char*()); - MOCK_CONST_METHOD0(GetEngineRoot, const char*()); - MOCK_CONST_METHOD0(GetExecutableFolder, const char* ()); - MOCK_METHOD0(GetDrillerManager, AZ::Debug::DrillerManager* ()); - MOCK_CONST_METHOD1(QueryApplicationType, void(AZ::ApplicationTypeQuery&)); - }; - - class MockEditorPythonConsoleInterface final - : public AzToolsFramework::EditorPythonConsoleInterface + static void ReflectTestTypes(AZ::ReflectContext* context) + { + AZ::BehaviorContext* behaviorContext = azrtti_cast(context); + if (behaviorContext) { - public: - MockEditorPythonConsoleInterface() - { - AZ::Interface::Register(this); - } + behaviorContext->Class() + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) + ->Attribute(AZ::Script::Attributes::Module, "scene.graph.test") + ->Method("GetId", [](const DataTypes::MockIGraphObject& self) + { + return self.m_id; + }) + ->Method("SetId", [](DataTypes::MockIGraphObject& self, int value) + { + self.m_id = value; + }) + ->Method("AddAndSet", [](DataTypes::MockIGraphObject& self, int lhs, int rhs) + { + self.m_id = lhs + rhs; + }); + } + } - ~MockEditorPythonConsoleInterface() - { - AZ::Interface::Unregister(this); - } + void SetUp() override + { + UnitTest::AllocatorsFixture::SetUp(); - MOCK_CONST_METHOD1(GetModuleList, void(AZStd::vector&)); - MOCK_CONST_METHOD1(GetGlobalFunctionList, void(GlobalFunctionCollection&)); - MOCK_METHOD1(FetchPythonTypeName, AZStd::string(const AZ::BehaviorParameter&)); - }; + m_serializeContext = AZStd::make_unique(); - // - // SceneGraphBehaviorScriptTest - // - class SceneGraphBehaviorScriptTest - : public UnitTest::AllocatorsFixture - { - public: - AZStd::unique_ptr m_componentApplication; - AZStd::unique_ptr m_editorPythonConsoleInterface; - AZStd::unique_ptr m_scriptContext; - AZStd::unique_ptr m_behaviorContext; - AZStd::unique_ptr m_serializeContext; - - static void TestExpectTrue(bool value) - { - EXPECT_TRUE(value); - } + m_behaviorContext = AZStd::make_unique(); + m_behaviorContext->Method("TestExpectTrue", &TestExpectTrue); + m_behaviorContext->Method("TestExpectEquals", &TestExpectEquals); - static void TestExpectEquals(AZ::s64 lhs, AZ::s64 rhs) - { - EXPECT_EQ(lhs, rhs); - } + AZ::MathReflect(m_behaviorContext.get()); + ReflectBehavior(m_behaviorContext.get()); + ReflectTestTypes(m_behaviorContext.get()); + MockBuilder::Reflect(m_behaviorContext.get()); - static void ReflectTestTypes(AZ::ReflectContext* context) - { - AZ::BehaviorContext* behaviorContext = azrtti_cast(context); - if (behaviorContext) + m_scriptContext = AZStd::make_unique(); + m_scriptContext->BindTo(m_behaviorContext.get()); + + m_componentApplication = AZStd::make_unique<::testing::NiceMock>(); + + ON_CALL(*m_componentApplication, GetBehaviorContext()) + .WillByDefault(::testing::Invoke([this]() { - behaviorContext->Class() - ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) - ->Attribute(AZ::Script::Attributes::Module, "scene.graph.test") - ->Method("GetId", [](const DataTypes::MockIGraphObject& self) - { - return self.m_id; - }) - ->Method("SetId", [](DataTypes::MockIGraphObject& self, int value) - { - self.m_id = value; - }) - ->Method("AddAndSet", [](DataTypes::MockIGraphObject& self, int lhs, int rhs) - { - self.m_id = lhs + rhs; - }); - } - } + return this->m_behaviorContext.get(); + })); - void SetUp() override - { - UnitTest::AllocatorsFixture::SetUp(); + ON_CALL(*m_componentApplication, GetSerializeContext()) + .WillByDefault(::testing::Invoke([this]() + { + return this->m_serializeContext.get(); + })); - m_serializeContext = AZStd::make_unique(); + m_editorPythonConsoleInterface = AZStd::make_unique(); + } - m_behaviorContext = AZStd::make_unique(); - m_behaviorContext->Method("TestExpectTrue", &TestExpectTrue); - m_behaviorContext->Method("TestExpectEquals", &TestExpectEquals); + void SetupEditorPythonConsoleInterface() + { + EXPECT_CALL(*m_editorPythonConsoleInterface, FetchPythonTypeName(::testing::_)) + .Times(4) + .WillRepeatedly(::testing::Invoke([](const AZ::BehaviorParameter&) {return "int"; })); + } - AZ::MathReflect(m_behaviorContext.get()); - ReflectBehavior(m_behaviorContext.get()); - ReflectTestTypes(m_behaviorContext.get()); - MockBuilder::Reflect(m_behaviorContext.get()); + void TearDown() override + { + m_scriptContext.reset(); + m_serializeContext.reset(); + m_behaviorContext.reset(); - m_scriptContext = AZStd::make_unique(); - m_scriptContext->BindTo(m_behaviorContext.get()); + UnitTest::AllocatorsFixture::TearDown(); + } - m_componentApplication = AZStd::make_unique<::testing::NiceMock>(); + void ExpectExecute(AZStd::string_view script) + { + EXPECT_TRUE(m_scriptContext->Execute(script.data())); + } + }; - ON_CALL(*m_componentApplication, GetBehaviorContext()) - .WillByDefault(::testing::Invoke([this]() - { - return this->m_behaviorContext.get(); - })); + TEST_F(SceneGraphBehaviorScriptTest, Scene_ScriptContext_Access) + { + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("builder:BuildSceneGraph()"); + ExpectExecute("scene = builder:GetScene()"); + ExpectExecute("TestExpectTrue(scene ~= nil)"); + ExpectExecute("TestExpectTrue(scene.name == 'unit_scene')"); + ExpectExecute("TestExpectTrue(scene.manifestFilename == 'manifest_filename')"); + ExpectExecute("TestExpectTrue(scene.sourceFilename == 'unit_source_filename')"); + ExpectExecute("TestExpectTrue(tostring(scene.sourceGuid) == '{1F2E6142-B0D8-42C6-A6E5-CD726DAA9EF0}')"); + ExpectExecute("TestExpectTrue(scene:GetOriginalSceneOrientation() == Scene.SceneOrientation_YUp)"); + } - ON_CALL(*m_componentApplication, GetSerializeContext()) - .WillByDefault(::testing::Invoke([this]() - { - return this->m_serializeContext.get(); - })); + TEST_F(SceneGraphBehaviorScriptTest, SceneGraph_ScriptContext_AccessMockNodes) + { + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("builder:BuildSceneGraph()"); + ExpectExecute("scene = builder:GetScene()"); + + // instance methods + ExpectExecute("TestExpectTrue(scene.graph ~= nil)"); + ExpectExecute("TestExpectTrue(scene.graph:GetRoot():IsValid())"); + ExpectExecute("TestExpectEquals(scene.graph:GetNodeCount(), 13)"); + ExpectExecute("nodeRoot = scene.graph:GetRoot()"); + ExpectExecute("nodeA = scene.graph:GetNodeChild(nodeRoot); TestExpectTrue(nodeA:IsValid())"); + ExpectExecute("TestExpectTrue(scene.graph:HasNodeContent(nodeA))"); + ExpectExecute("nodeC = scene.graph:GetNodeChild(nodeA); TestExpectTrue(nodeC:IsValid())"); + ExpectExecute("nodeNameC = scene.graph:GetNodeName(nodeC); TestExpectTrue(nodeNameC ~= nil)"); + ExpectExecute("nodeE = scene.graph:GetNodeChild(nodeC); TestExpectTrue(nodeE:IsValid())"); + ExpectExecute("TestExpectTrue(scene.graph:HasNodeSibling(nodeE))"); + ExpectExecute("TestExpectTrue(scene.graph:HasNodeChild(nodeE))"); + ExpectExecute("TestExpectTrue(scene.graph:HasNodeParent(nodeE))"); + ExpectExecute("nodeG = scene.graph:GetNodeChild(nodeE); TestExpectTrue(nodeG:IsValid())"); + ExpectExecute("TestExpectTrue(scene.graph:GetNodeParent(nodeG) == nodeE)"); + ExpectExecute("nodeH = scene.graph:GetNodeSibling(nodeG); TestExpectTrue(nodeH:IsValid())"); + ExpectExecute("TestExpectTrue(scene.graph:GetNodeName(nodeH):GetPath() == 'A.C.E.H')"); + ExpectExecute("nodeB = scene.graph:GetNodeSibling(nodeA); TestExpectTrue(nodeB:IsValid())"); + ExpectExecute("nodeK = scene.graph:GetNodeChild(nodeB); TestExpectTrue(nodeK:IsValid())"); + ExpectExecute("TestExpectTrue(scene.graph:FindWithPath('B.K') == nodeK)"); + ExpectExecute("nodeL = scene.graph:GetNodeChild(nodeK); TestExpectTrue(nodeL:IsValid())"); + ExpectExecute("TestExpectTrue(scene.graph:FindWithRootAndPath(nodeK, 'L') == nodeL)"); + + // static methods + ExpectExecute("TestExpectTrue(scene.graph.IsValidName('A'))"); + ExpectExecute("TestExpectTrue(scene.graph.GetNodeSeperationCharacter() == string.byte('.'))"); + } - m_editorPythonConsoleInterface = AZStd::make_unique(); - } + TEST_F(SceneGraphBehaviorScriptTest, SceneGraphNodeIndex_ScriptContext_AccessMockNodes) + { + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("builder:BuildSceneGraph()"); + ExpectExecute("scene = builder:GetScene()"); + ExpectExecute("nodeA = scene.graph:GetNodeChild(scene.graph:GetRoot())"); + ExpectExecute("TestExpectTrue(nodeA:IsValid())"); + ExpectExecute("TestExpectEquals(nodeA:AsNumber(), 1)"); + ExpectExecute("TestExpectEquals(scene.graph:GetRoot():Distance(nodeA), 1)"); + ExpectExecute("TestExpectEquals(nodeA:Distance(scene.graph:GetRoot()), -1)"); + ExpectExecute("TestExpectTrue(nodeA == scene.graph:FindWithPath('A'))"); + } - void SetupEditorPythonConsoleInterface() - { - EXPECT_CALL(*m_editorPythonConsoleInterface, FetchPythonTypeName(::testing::_)) - .Times(4) - .WillRepeatedly(::testing::Invoke([](const AZ::BehaviorParameter&) {return "int"; })); - } + TEST_F(SceneGraphBehaviorScriptTest, SceneGraphName_ScriptContext_AccessMockNodes) + { + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("builder:BuildSceneGraph()"); + ExpectExecute("scene = builder:GetScene()"); + ExpectExecute("nodeG = scene.graph:FindWithPath('A.C.E.G')"); + ExpectExecute("nodeNameG = scene.graph:GetNodeName(nodeG)"); + ExpectExecute("TestExpectTrue(nodeNameG:GetPath() == 'A.C.E.G')"); + ExpectExecute("TestExpectTrue(nodeNameG:GetName() == 'G')"); + } - void TearDown() override - { - m_scriptContext.reset(); - m_serializeContext.reset(); - m_behaviorContext.reset(); + TEST_F(SceneGraphBehaviorScriptTest, SceneGraphIGraphNode_ScriptContext_AccessMockNodes) + { + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("builder:BuildSceneGraph()"); + ExpectExecute("scene = builder:GetScene()"); + ExpectExecute("nodeG = scene.graph:FindWithPath('A.C.E.G')"); + ExpectExecute("proxy = scene.graph:GetNodeContent(nodeG)"); + ExpectExecute("TestExpectTrue(proxy:CastWithTypeName('MockIGraphObject'))"); + ExpectExecute("value = proxy:Invoke('GetId', vector_any())"); + ExpectExecute("TestExpectEquals(value, 7)"); + ExpectExecute("setIdArgs = vector_any(); setIdArgs:push_back(8);"); + ExpectExecute("proxy:Invoke('SetId', setIdArgs)"); + ExpectExecute("value = proxy:Invoke('GetId', vector_any())"); + ExpectExecute("TestExpectEquals(value, 8)"); + ExpectExecute("addArgs = vector_any(); addArgs:push_back(8); addArgs:push_back(9)"); + ExpectExecute("proxy:Invoke('AddAndSet', addArgs)"); + ExpectExecute("value = proxy:Invoke('GetId', vector_any())"); + ExpectExecute("TestExpectEquals(value, 17)"); + } - UnitTest::AllocatorsFixture::TearDown(); - } + TEST_F(SceneGraphBehaviorScriptTest, GraphObjectProxy_GetClassInfo_Loads) + { + SetupEditorPythonConsoleInterface(); + + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("builder:BuildSceneGraph()"); + ExpectExecute("scene = builder:GetScene()"); + ExpectExecute("nodeG = scene.graph:FindWithPath('A.C.E.G')"); + ExpectExecute("proxy = scene.graph:GetNodeContent(nodeG)"); + ExpectExecute("TestExpectTrue(proxy:CastWithTypeName('MockIGraphObject'))"); + ExpectExecute("info = proxy:GetClassInfo()"); + ExpectExecute("TestExpectTrue(info ~= nil)"); + } - void ExpectExecute(AZStd::string_view script) - { - EXPECT_TRUE(m_scriptContext->Execute(script.data())); - } - }; + TEST_F(SceneGraphBehaviorScriptTest, GraphObjectProxy_GetClassInfo_CorrectFormats) + { + SetupEditorPythonConsoleInterface(); + + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("builder:BuildSceneGraph()"); + ExpectExecute("scene = builder:GetScene()"); + ExpectExecute("nodeG = scene.graph:FindWithPath('A.C.E.G')"); + ExpectExecute("proxy = scene.graph:GetNodeContent(nodeG)"); + ExpectExecute("TestExpectTrue(proxy:CastWithTypeName('MockIGraphObject'))"); + ExpectExecute("info = proxy:GetClassInfo()"); + ExpectExecute("TestExpectTrue(info.className == 'MockIGraphObject')"); + ExpectExecute("TestExpectTrue(info.classUuid == '{66A082CC-851D-4E1F-ABBD-45B58A216CFA}')"); + ExpectExecute("TestExpectTrue(info.methodList[1] == 'def GetId(self) -> int')"); + ExpectExecute("TestExpectTrue(info.methodList[2] == 'def SetId(self, arg1: int) -> None')"); + ExpectExecute("TestExpectTrue(info.methodList[3] == 'def AddAndSet(self, arg1: int, arg2: int) -> None')"); + } - TEST_F(SceneGraphBehaviorScriptTest, Scene_ScriptContext_Access) - { - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("builder:BuildSceneGraph()"); - ExpectExecute("scene = builder:GetScene()"); - ExpectExecute("TestExpectTrue(scene ~= nil)"); - ExpectExecute("TestExpectTrue(scene.name == 'unit_scene')"); - ExpectExecute("TestExpectTrue(scene.manifestFilename == 'manifest_filename')"); - ExpectExecute("TestExpectTrue(scene.sourceFilename == 'unit_source_filename')"); - ExpectExecute("TestExpectTrue(tostring(scene.sourceGuid) == '{1F2E6142-B0D8-42C6-A6E5-CD726DAA9EF0}')"); - ExpectExecute("TestExpectTrue(scene:GetOriginalSceneOrientation() == Scene.SceneOrientation_YUp)"); - } + TEST_F(SceneGraphBehaviorScriptTest, ExportProduct_ExpectedClassesAndFields_Work) + { + ExpectExecute("mockAssetType = Uuid.CreateString('{B7AD6A54-963F-4F0F-A70E-1CFC0364BE6B}')"); + ExpectExecute("exportProduct = ExportProduct()"); + ExpectExecute("exportProduct.filename = 'some/file.name'"); + ExpectExecute("exportProduct.sourceId = Uuid.CreateString('{A19F5FDB-C5FB-478F-A0B0-B697D2C10DB5}', 0)"); + ExpectExecute("exportProduct.assetType = mockAssetType"); + ExpectExecute("exportProduct.subId = 10101"); + ExpectExecute("TestExpectEquals(exportProduct.subId, 10101)"); + ExpectExecute("TestExpectEquals(exportProduct.productDependencies:GetSize(), 0)"); + + ExpectExecute("exportProductDep = ExportProduct()"); + ExpectExecute("exportProductDep.filename = 'some/file.dep'"); + ExpectExecute("exportProductDep.sourceId = Uuid.CreateString('{A19F5FDB-C5FB-478F-A0B0-B697D2C10DB5}', 0)"); + ExpectExecute("exportProductDep.assetType = mockAssetType"); + ExpectExecute("exportProductDep.subId = 2"); + + ExpectExecute("exportProductList = ExportProductList()"); + ExpectExecute("exportProductList:AddProduct(exportProduct)"); + ExpectExecute("exportProductList:AddProduct(exportProductDep)"); + ExpectExecute("productList = exportProductList:GetProducts()"); + ExpectExecute("TestExpectEquals(productList:GetSize(), 2)"); + ExpectExecute("exportProductList:AddDependencyToProduct(exportProduct.filename, exportProductDep)"); + ExpectExecute("TestExpectEquals(productList:Front().productDependencies:GetSize(), 1)"); + } - TEST_F(SceneGraphBehaviorScriptTest, SceneGraph_ScriptContext_AccessMockNodes) - { - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("builder:BuildSceneGraph()"); - ExpectExecute("scene = builder:GetScene()"); - - // instance methods - ExpectExecute("TestExpectTrue(scene.graph ~= nil)"); - ExpectExecute("TestExpectTrue(scene.graph:GetRoot():IsValid())"); - ExpectExecute("TestExpectEquals(scene.graph:GetNodeCount(), 13)"); - ExpectExecute("nodeRoot = scene.graph:GetRoot()"); - ExpectExecute("nodeA = scene.graph:GetNodeChild(nodeRoot); TestExpectTrue(nodeA:IsValid())"); - ExpectExecute("TestExpectTrue(scene.graph:HasNodeContent(nodeA))"); - ExpectExecute("nodeC = scene.graph:GetNodeChild(nodeA); TestExpectTrue(nodeC:IsValid())"); - ExpectExecute("nodeNameC = scene.graph:GetNodeName(nodeC); TestExpectTrue(nodeNameC ~= nil)"); - ExpectExecute("nodeE = scene.graph:GetNodeChild(nodeC); TestExpectTrue(nodeE:IsValid())"); - ExpectExecute("TestExpectTrue(scene.graph:HasNodeSibling(nodeE))"); - ExpectExecute("TestExpectTrue(scene.graph:HasNodeChild(nodeE))"); - ExpectExecute("TestExpectTrue(scene.graph:HasNodeParent(nodeE))"); - ExpectExecute("nodeG = scene.graph:GetNodeChild(nodeE); TestExpectTrue(nodeG:IsValid())"); - ExpectExecute("TestExpectTrue(scene.graph:GetNodeParent(nodeG) == nodeE)"); - ExpectExecute("nodeH = scene.graph:GetNodeSibling(nodeG); TestExpectTrue(nodeH:IsValid())"); - ExpectExecute("TestExpectTrue(scene.graph:GetNodeName(nodeH):GetPath() == 'A.C.E.H')"); - ExpectExecute("nodeB = scene.graph:GetNodeSibling(nodeA); TestExpectTrue(nodeB:IsValid())"); - ExpectExecute("nodeK = scene.graph:GetNodeChild(nodeB); TestExpectTrue(nodeK:IsValid())"); - ExpectExecute("TestExpectTrue(scene.graph:FindWithPath('B.K') == nodeK)"); - ExpectExecute("nodeL = scene.graph:GetNodeChild(nodeK); TestExpectTrue(nodeL:IsValid())"); - ExpectExecute("TestExpectTrue(scene.graph:FindWithRootAndPath(nodeK, 'L') == nodeL)"); - - // static methods - ExpectExecute("TestExpectTrue(scene.graph.IsValidName('A'))"); - ExpectExecute("TestExpectTrue(scene.graph.GetNodeSeperationCharacter() == string.byte('.'))"); - } + // + // SceneManifestBehaviorScriptTest is meant to test the script abilities of the SceneManifest + // + class SceneManifestBehaviorScriptTest + : public UnitTest::AllocatorsFixture + { + public: + AZStd::unique_ptr m_componentApplication; + AZStd::unique_ptr m_scriptContext; + AZStd::unique_ptr m_behaviorContext; + AZStd::unique_ptr m_serializeContext; + AZStd::unique_ptr m_jsonRegistrationContext; + AZStd::string_view m_jsonMockData = R"JSON('{"values":[{"$type":"MockManifestRule","value":0.1},{"$type":"MockManifestRule","value":2.3},{"$type":"MockManifestRule","value":4.5}]}')JSON"; + + static void TestAssertTrue(bool value) + { + EXPECT_TRUE(value); + } - TEST_F(SceneGraphBehaviorScriptTest, SceneGraphNodeIndex_ScriptContext_AccessMockNodes) - { - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("builder:BuildSceneGraph()"); - ExpectExecute("scene = builder:GetScene()"); - ExpectExecute("nodeA = scene.graph:GetNodeChild(scene.graph:GetRoot())"); - ExpectExecute("TestExpectTrue(nodeA:IsValid())"); - ExpectExecute("TestExpectEquals(nodeA:AsNumber(), 1)"); - ExpectExecute("TestExpectEquals(scene.graph:GetRoot():Distance(nodeA), 1)"); - ExpectExecute("TestExpectEquals(nodeA:Distance(scene.graph:GetRoot()), -1)"); - ExpectExecute("TestExpectTrue(nodeA == scene.graph:FindWithPath('A'))"); - } + void SetUp() override + { + UnitTest::AllocatorsFixture::SetUp(); - TEST_F(SceneGraphBehaviorScriptTest, SceneGraphName_ScriptContext_AccessMockNodes) - { - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("builder:BuildSceneGraph()"); - ExpectExecute("scene = builder:GetScene()"); - ExpectExecute("nodeG = scene.graph:FindWithPath('A.C.E.G')"); - ExpectExecute("nodeNameG = scene.graph:GetNodeName(nodeG)"); - ExpectExecute("TestExpectTrue(nodeNameG:GetPath() == 'A.C.E.G')"); - ExpectExecute("TestExpectTrue(nodeNameG:GetName() == 'G')"); - } + m_serializeContext = AZStd::make_unique(); + MockBuilder::Reflect(m_serializeContext.get()); + MockManifestRule::Reflect(m_serializeContext.get()); + ReflectTypes(m_serializeContext.get()); - TEST_F(SceneGraphBehaviorScriptTest, SceneGraphIGraphNode_ScriptContext_AccessMockNodes) - { - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("builder:BuildSceneGraph()"); - ExpectExecute("scene = builder:GetScene()"); - ExpectExecute("nodeG = scene.graph:FindWithPath('A.C.E.G')"); - ExpectExecute("proxy = scene.graph:GetNodeContent(nodeG)"); - ExpectExecute("TestExpectTrue(proxy:CastWithTypeName('MockIGraphObject'))"); - ExpectExecute("value = proxy:Invoke('GetId', vector_any())"); - ExpectExecute("TestExpectEquals(value, 7)"); - ExpectExecute("setIdArgs = vector_any(); setIdArgs:push_back(8);"); - ExpectExecute("proxy:Invoke('SetId', setIdArgs)"); - ExpectExecute("value = proxy:Invoke('GetId', vector_any())"); - ExpectExecute("TestExpectEquals(value, 8)"); - ExpectExecute("addArgs = vector_any(); addArgs:push_back(8); addArgs:push_back(9)"); - ExpectExecute("proxy:Invoke('AddAndSet', addArgs)"); - ExpectExecute("value = proxy:Invoke('GetId', vector_any())"); - ExpectExecute("TestExpectEquals(value, 17)"); - } + m_behaviorContext = AZStd::make_unique(); + m_behaviorContext->Method("TestAssertTrue", &TestAssertTrue); + AZ::MathReflect(m_behaviorContext.get()); + MockBuilder::Reflect(m_behaviorContext.get()); + MockManifestRule::Reflect(m_behaviorContext.get()); + ReflectBehavior(m_behaviorContext.get()); - TEST_F(SceneGraphBehaviorScriptTest, GraphObjectProxy_GetClassInfo_Loads) - { - SetupEditorPythonConsoleInterface(); - - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("builder:BuildSceneGraph()"); - ExpectExecute("scene = builder:GetScene()"); - ExpectExecute("nodeG = scene.graph:FindWithPath('A.C.E.G')"); - ExpectExecute("proxy = scene.graph:GetNodeContent(nodeG)"); - ExpectExecute("TestExpectTrue(proxy:CastWithTypeName('MockIGraphObject'))"); - ExpectExecute("info = proxy:GetClassInfo()"); - ExpectExecute("TestExpectTrue(info ~= nil)"); - } + m_jsonRegistrationContext = AZStd::make_unique(); + AZ::JsonSystemComponent::Reflect(m_jsonRegistrationContext.get()); - TEST_F(SceneGraphBehaviorScriptTest, GraphObjectProxy_GetClassInfo_CorrectFormats) - { - SetupEditorPythonConsoleInterface(); - - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("builder:BuildSceneGraph()"); - ExpectExecute("scene = builder:GetScene()"); - ExpectExecute("nodeG = scene.graph:FindWithPath('A.C.E.G')"); - ExpectExecute("proxy = scene.graph:GetNodeContent(nodeG)"); - ExpectExecute("TestExpectTrue(proxy:CastWithTypeName('MockIGraphObject'))"); - ExpectExecute("info = proxy:GetClassInfo()"); - ExpectExecute("TestExpectTrue(info.className == 'MockIGraphObject')"); - ExpectExecute("TestExpectTrue(info.classUuid == '{66A082CC-851D-4E1F-ABBD-45B58A216CFA}')"); - ExpectExecute("TestExpectTrue(info.methodList[1] == 'def GetId(self) -> int')"); - ExpectExecute("TestExpectTrue(info.methodList[2] == 'def SetId(self, arg1: int) -> None')"); - ExpectExecute("TestExpectTrue(info.methodList[3] == 'def AddAndSet(self, arg1: int, arg2: int) -> None')"); - } + m_scriptContext = AZStd::make_unique(); + m_scriptContext->BindTo(m_behaviorContext.get()); - // - // SceneManifestBehaviorScriptTest is meant to test the script abilities of the SceneManifest - // - class SceneManifestBehaviorScriptTest - : public UnitTest::AllocatorsFixture - { - public: - AZStd::unique_ptr m_componentApplication; - AZStd::unique_ptr m_scriptContext; - AZStd::unique_ptr m_behaviorContext; - AZStd::unique_ptr m_serializeContext; - AZStd::unique_ptr m_jsonRegistrationContext; - AZStd::string_view m_jsonMockData = R"JSON('{"values":[{"$type":"MockManifestRule","value":0.1},{"$type":"MockManifestRule","value":2.3},{"$type":"MockManifestRule","value":4.5}]}')JSON"; - - static void TestAssertTrue(bool value) - { - EXPECT_TRUE(value); - } + m_componentApplication = AZStd::make_unique<::testing::NiceMock>(); - void SetUp() override + ON_CALL(*m_componentApplication, GetBehaviorContext()).WillByDefault(::testing::Invoke([this]() { - UnitTest::AllocatorsFixture::SetUp(); - - m_serializeContext = AZStd::make_unique(); - MockBuilder::Reflect(m_serializeContext.get()); - MockManifestRule::Reflect(m_serializeContext.get()); - ReflectTypes(m_serializeContext.get()); - - m_behaviorContext = AZStd::make_unique(); - m_behaviorContext->Method("TestAssertTrue", &TestAssertTrue); - AZ::MathReflect(m_behaviorContext.get()); - MockBuilder::Reflect(m_behaviorContext.get()); - MockManifestRule::Reflect(m_behaviorContext.get()); - ReflectBehavior(m_behaviorContext.get()); - - m_jsonRegistrationContext = AZStd::make_unique(); - AZ::JsonSystemComponent::Reflect(m_jsonRegistrationContext.get()); - - m_scriptContext = AZStd::make_unique(); - m_scriptContext->BindTo(m_behaviorContext.get()); - - m_componentApplication = AZStd::make_unique<::testing::NiceMock>(); - - ON_CALL(*m_componentApplication, GetBehaviorContext()).WillByDefault(::testing::Invoke([this]() - { - return this->m_behaviorContext.get(); - })); - - ON_CALL(*m_componentApplication, GetSerializeContext()).WillByDefault(::testing::Invoke([this]() - { - return this->m_serializeContext.get(); - })); - - ON_CALL(*m_componentApplication, GetJsonRegistrationContext()).WillByDefault(::testing::Invoke([this]() - { - return this->m_jsonRegistrationContext.get(); - })); - } + return this->m_behaviorContext.get(); + })); - void TearDown() override + ON_CALL(*m_componentApplication, GetSerializeContext()).WillByDefault(::testing::Invoke([this]() { - m_jsonRegistrationContext->EnableRemoveReflection(); - AZ::JsonSystemComponent::Reflect(m_jsonRegistrationContext.get()); - m_jsonRegistrationContext->DisableRemoveReflection(); - - m_jsonRegistrationContext.reset(); - m_serializeContext.reset(); - m_scriptContext.reset(); - m_behaviorContext.reset(); - m_componentApplication.reset(); - UnitTest::AllocatorsFixture::TearDown(); - } + return this->m_serializeContext.get(); + })); - void ExpectExecute(AZStd::string_view script) + ON_CALL(*m_componentApplication, GetJsonRegistrationContext()).WillByDefault(::testing::Invoke([this]() { - EXPECT_TRUE(m_scriptContext->Execute(script.data())); - } - }; - - TEST_F(SceneManifestBehaviorScriptTest, SceneManifest_ScriptContext_GetDefaultJSON) - { - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("scene = builder:GetScene()"); - ExpectExecute("manifest = scene.manifest:ExportToJson()"); - ExpectExecute(R"JSON(TestAssertTrue(manifest == '{}'))JSON"); - } + return this->m_jsonRegistrationContext.get(); + })); + } - TEST_F(SceneManifestBehaviorScriptTest, SceneManifest_ScriptContext_GetComplexJSON) - { - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("scene = builder:GetScene()"); - ExpectExecute("builder:BuildSceneGraph()"); - ExpectExecute("manifest = scene.manifest:ExportToJson()"); - auto read = AZStd::fixed_string<1024>::format("TestAssertTrue(manifest == %s)", m_jsonMockData.data()); - ExpectExecute(read); - } + void TearDown() override + { + m_jsonRegistrationContext->EnableRemoveReflection(); + AZ::JsonSystemComponent::Reflect(m_jsonRegistrationContext.get()); + m_jsonRegistrationContext->DisableRemoveReflection(); + + m_jsonRegistrationContext.reset(); + m_serializeContext.reset(); + m_scriptContext.reset(); + m_behaviorContext.reset(); + m_componentApplication.reset(); + UnitTest::AllocatorsFixture::TearDown(); + } - TEST_F(SceneManifestBehaviorScriptTest, SceneManifest_ScriptContext_SetComplexJSON) - { - ExpectExecute("builder = MockBuilder()"); - ExpectExecute("scene = builder:GetScene()"); - ExpectExecute("manifest = scene.manifest:ExportToJson()"); - ExpectExecute(R"JSON(TestAssertTrue(manifest == '{}'))JSON"); - auto load = AZStd::fixed_string<1024>::format("TestAssertTrue(scene.manifest:ImportFromJson(%s))", m_jsonMockData.data()); - ExpectExecute(load); - ExpectExecute("manifest = scene.manifest:ExportToJson()"); - auto read = AZStd::fixed_string<1024>::format("TestAssertTrue(manifest == %s)", m_jsonMockData.data()); - ExpectExecute(read); - } + void ExpectExecute(AZStd::string_view script) + { + EXPECT_TRUE(m_scriptContext->Execute(script.data())); } + }; + + TEST_F(SceneManifestBehaviorScriptTest, SceneManifest_ScriptContext_GetDefaultJSON) + { + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("scene = builder:GetScene()"); + ExpectExecute("manifest = scene.manifest:ExportToJson()"); + ExpectExecute(R"JSON(TestAssertTrue(manifest == '{}'))JSON"); } -} + + TEST_F(SceneManifestBehaviorScriptTest, SceneManifest_ScriptContext_GetComplexJSON) + { + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("scene = builder:GetScene()"); + ExpectExecute("builder:BuildSceneGraph()"); + ExpectExecute("manifest = scene.manifest:ExportToJson()"); + auto read = AZStd::fixed_string<1024>::format("TestAssertTrue(manifest == %s)", m_jsonMockData.data()); + ExpectExecute(read); + } + + TEST_F(SceneManifestBehaviorScriptTest, SceneManifest_ScriptContext_SetComplexJSON) + { + ExpectExecute("builder = MockBuilder()"); + ExpectExecute("scene = builder:GetScene()"); + ExpectExecute("manifest = scene.manifest:ExportToJson()"); + ExpectExecute(R"JSON(TestAssertTrue(manifest == '{}'))JSON"); + auto load = AZStd::fixed_string<1024>::format("TestAssertTrue(scene.manifest:ImportFromJson(%s))", m_jsonMockData.data()); + ExpectExecute(load); + ExpectExecute("manifest = scene.manifest:ExportToJson()"); + auto read = AZStd::fixed_string<1024>::format("TestAssertTrue(manifest == %s)", m_jsonMockData.data()); + ExpectExecute(read); + } + +} // namespace AZ::SceneAPI::Containers diff --git a/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.cpp b/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.cpp index 5ae547b577..b7fda1e0dc 100644 --- a/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.cpp +++ b/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.cpp @@ -25,213 +25,319 @@ #include #include #include +#include -namespace AZ +namespace AZ::SceneAPI::Behaviors { - namespace SceneAPI + class EditorPythonConsoleNotificationHandler final + : protected AzToolsFramework::EditorPythonConsoleNotificationBus::Handler { - namespace Behaviors + public: + EditorPythonConsoleNotificationHandler() { - class EditorPythonConsoleNotificationHandler final - : protected AzToolsFramework::EditorPythonConsoleNotificationBus::Handler - { - public: - EditorPythonConsoleNotificationHandler() - { - BusConnect(); - } + BusConnect(); + } - ~EditorPythonConsoleNotificationHandler() - { - BusDisconnect(); - } + ~EditorPythonConsoleNotificationHandler() + { + BusDisconnect(); + } - //////////////////////////////////////////////////////////////////////////////////////////// - // AzToolsFramework::EditorPythonConsoleNotifications - void OnTraceMessage([[maybe_unused]] AZStd::string_view message) override - { - using namespace AZ::SceneAPI::Utilities; - AZ_TracePrintf(LogWindow, "%.*s \n", AZ_STRING_ARG(message)); - } + //////////////////////////////////////////////////////////////////////////////////////////// + // AzToolsFramework::EditorPythonConsoleNotifications + void OnTraceMessage([[maybe_unused]] AZStd::string_view message) override + { + using namespace AZ::SceneAPI::Utilities; + AZ_TracePrintf(LogWindow, "%.*s \n", AZ_STRING_ARG(message)); + } - void OnErrorMessage([[maybe_unused]] AZStd::string_view message) override - { - using namespace AZ::SceneAPI::Utilities; - AZ_TracePrintf(ErrorWindow, "[ERROR] %.*s \n", AZ_STRING_ARG(message)); - } + void OnErrorMessage([[maybe_unused]] AZStd::string_view message) override + { + using namespace AZ::SceneAPI::Utilities; + AZ_TracePrintf(ErrorWindow, "[ERROR] %.*s \n", AZ_STRING_ARG(message)); + } - void OnExceptionMessage([[maybe_unused]] AZStd::string_view message) override - { - using namespace AZ::SceneAPI::Utilities; - AZ_TracePrintf(ErrorWindow, "[EXCEPTION] %.*s \n", AZ_STRING_ARG(message)); - } - }; + void OnExceptionMessage([[maybe_unused]] AZStd::string_view message) override + { + using namespace AZ::SceneAPI::Utilities; + AZ_TracePrintf(ErrorWindow, "[EXCEPTION] %.*s \n", AZ_STRING_ARG(message)); + } + }; - // a event bus to signal during scene building - struct ScriptBuildingNotifications - : public AZ::EBusTraits - { - virtual AZStd::string OnUpdateManifest(Containers::Scene& scene) = 0; - }; - using ScriptBuildingNotificationBus = AZ::EBus; + using ExportProductList = AZ::SceneAPI::Events::ExportProductList; + + // a event bus to signal during scene building + struct ScriptBuildingNotifications + : public AZ::EBusTraits + { + virtual AZStd::string OnUpdateManifest(Containers::Scene& scene) = 0; + virtual ExportProductList OnPrepareForExport( + const Containers::Scene& scene, + AZStd::string_view outputDirectory, + AZStd::string_view platformIdentifier, + const ExportProductList& productList) = 0; + }; + using ScriptBuildingNotificationBus = AZ::EBus; + + // a back end to handle scene builder events for a script + struct ScriptBuildingNotificationBusHandler final + : public ScriptBuildingNotificationBus::Handler + , public AZ::BehaviorEBusHandler + { + AZ_EBUS_BEHAVIOR_BINDER( + ScriptBuildingNotificationBusHandler, + "{DF2B51DE-A4D0-4139-B5D0-DF185832380D}", + AZ::SystemAllocator, + OnUpdateManifest, + OnPrepareForExport); - // a back end to handle scene builder events for a script - struct ScriptBuildingNotificationBusHandler final - : public ScriptBuildingNotificationBus::Handler - , public AZ::BehaviorEBusHandler + virtual ~ScriptBuildingNotificationBusHandler() = default; + + AZStd::string OnUpdateManifest(Containers::Scene& scene) override + { + AZStd::string result; + CallResult(result, FN_OnUpdateManifest, scene); + return result; + } + + ExportProductList OnPrepareForExport( + const Containers::Scene& scene, + AZStd::string_view outputDirectory, + AZStd::string_view platformIdentifier, + const ExportProductList& productList) override + { + ExportProductList result; + CallResult(result, FN_OnPrepareForExport, scene, outputDirectory, platformIdentifier, productList); + return result; + } + + static void Reflect(AZ::ReflectContext* context) + { + if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) { - AZ_EBUS_BEHAVIOR_BINDER( - ScriptBuildingNotificationBusHandler, - "{DF2B51DE-A4D0-4139-B5D0-DF185832380D}", - AZ::SystemAllocator, - OnUpdateManifest); + behaviorContext->EBus("ScriptBuildingNotificationBus") + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) + ->Attribute(AZ::Script::Attributes::Module, "scene") + ->Handler() + ->Event("OnUpdateManifest", &ScriptBuildingNotificationBus::Events::OnUpdateManifest) + ->Event("OnPrepareForExport", &ScriptBuildingNotificationBus::Events::OnPrepareForExport); + } + } + }; - virtual ~ScriptBuildingNotificationBusHandler() = default; + struct ScriptProcessorRuleBehavior::ExportEventHandler final + : public AZ::SceneAPI::SceneCore::ExportingComponent + { + using PreExportEventContextFunction = AZStd::function; + PreExportEventContextFunction m_preExportEventContextFunction; - AZStd::string OnUpdateManifest(Containers::Scene& scene) override - { - AZStd::string result; - CallResult(result, FN_OnUpdateManifest, scene); - return result; - } + ExportEventHandler(PreExportEventContextFunction preExportEventContextFunction) + : m_preExportEventContextFunction(preExportEventContextFunction) + { + BindToCall(&ExportEventHandler::PrepareForExport); + AZ::SceneAPI::SceneCore::ExportingComponent::Activate(); + } - static void Reflect(AZ::ReflectContext* context) - { - if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) - { - behaviorContext->EBus("ScriptBuildingNotificationBus") - ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) - ->Attribute(AZ::Script::Attributes::Module, "scene") - ->Handler() - ->Event("OnUpdateManifest", &ScriptBuildingNotificationBus::Events::OnUpdateManifest); - } - } - }; + ~ExportEventHandler() + { + AZ::SceneAPI::SceneCore::ExportingComponent::Deactivate(); + } + + // this allows a Python script to add product assets on "scene export" + Events::ProcessingResult PrepareForExport(Events::PreExportEventContext& context) + { + return m_preExportEventContextFunction(context) ? Events::ProcessingResult::Success : Events::ProcessingResult::Failure; + } + }; + + void ScriptProcessorRuleBehavior::Activate() + { + Events::AssetImportRequestBus::Handler::BusConnect(); + m_exportEventHandler = AZStd::make_shared([this](Events::PreExportEventContext& context) + { + return this->DoPrepareForExport(context); + }); + } + + void ScriptProcessorRuleBehavior::Deactivate() + { + m_exportEventHandler.reset(); + Events::AssetImportRequestBus::Handler::BusDisconnect(); + UnloadPython(); + } + + bool ScriptProcessorRuleBehavior::LoadPython(const AZ::SceneAPI::Containers::Scene& scene) + { + if (m_editorPythonEventsInterface && !m_scriptFilename.empty()) + { + return true; + } + + // get project folder + auto settingsRegistry = AZ::SettingsRegistry::Get(); + AZ::IO::FixedMaxPath projectPath; + if (!settingsRegistry->Get(projectPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectPath)) + { + return false; + } - void ScriptProcessorRuleBehavior::Activate() + const AZ::SceneAPI::Containers::SceneManifest& manifest = scene.GetManifest(); + auto view = Containers::MakeDerivedFilterView(manifest.GetValueStorage()); + for (const auto& scriptItem : view) + { + AZ::IO::FixedMaxPath scriptFilename(scriptItem.GetScriptFilename()); + if (scriptFilename.empty()) { - Events::AssetImportRequestBus::Handler::BusConnect(); + AZ_Warning("scene", false, "Skipping an empty script filename in (%s)", scene.GetManifestFilename().c_str()); + continue; } - void ScriptProcessorRuleBehavior::Deactivate() + // check for file exist via absolute path + if (!IO::FileIOBase::GetInstance()->Exists(scriptFilename.c_str())) { - Events::AssetImportRequestBus::Handler::BusDisconnect(); - if (m_editorPythonEventsInterface) + // check for script in the project folder + AZ::IO::FixedMaxPath projectScriptPath = projectPath / scriptFilename; + if (!IO::FileIOBase::GetInstance()->Exists(projectScriptPath.c_str())) { - const bool silenceWarnings = true; - m_editorPythonEventsInterface->StopPython(silenceWarnings); - m_editorPythonEventsInterface = nullptr; - + AZ_Warning("scene", false, "Skipping a missing script (%s) in manifest file (%s)", + scriptFilename.c_str(), + scene.GetManifestFilename().c_str()); + continue; } + scriptFilename = AZStd::move(projectScriptPath); } - void ScriptProcessorRuleBehavior::Reflect(ReflectContext* context) + // lazy load the Python interface + auto editorPythonEventsInterface = AZ::Interface::Get(); + if (editorPythonEventsInterface->IsPythonActive() == false) { - ScriptBuildingNotificationBusHandler::Reflect(context); - - SerializeContext* serializeContext = azrtti_cast(context); - if (serializeContext) + const bool silenceWarnings = false; + if (editorPythonEventsInterface->StartPython(silenceWarnings) == false) { - serializeContext->Class()->Version(1); + editorPythonEventsInterface = nullptr; } } - Events::ProcessingResult ScriptProcessorRuleBehavior::UpdateManifest( - Containers::Scene& scene, - Events::AssetImportRequest::ManifestAction action, - [[maybe_unused]] Events::AssetImportRequest::RequestingApplication requester) + // both Python and the script need to be ready + if (editorPythonEventsInterface == nullptr || scriptFilename.empty()) { - using namespace AzToolsFramework; + AZ_Warning("scene", false,"The scene manifest (%s) attempted to use script(%s) but Python is not enabled;" + "please add the EditorPythonBinding gem & PythonAssetBuilder gem to your project.", + scene.GetManifestFilename().c_str(), scriptFilename.c_str()); - if (action != ManifestAction::Update) - { - return Events::ProcessingResult::Ignored; - } + return false; + } - // get project folder - auto settingsRegistry = AZ::SettingsRegistry::Get(); - AZ::IO::FixedMaxPath projectPath; - if (!settingsRegistry->Get(projectPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectPath)) - { - return Events::ProcessingResult::Ignored; - } + m_editorPythonEventsInterface = editorPythonEventsInterface; + m_scriptFilename = scriptFilename.c_str(); + return true; + } + return false; + } + + void ScriptProcessorRuleBehavior::UnloadPython() + { + if (m_editorPythonEventsInterface) + { + const bool silenceWarnings = true; + m_editorPythonEventsInterface->StopPython(silenceWarnings); + m_editorPythonEventsInterface = nullptr; + } + } + + bool ScriptProcessorRuleBehavior::DoPrepareForExport(Events::PreExportEventContext& context) + { + using namespace AzToolsFramework; + + auto executeCallback = [this, &context]() + { + // set up script's hook callback + EditorPythonRunnerRequestBus::Broadcast(&EditorPythonRunnerRequestBus::Events::ExecuteByFilename, + m_scriptFilename.c_str()); + + // call script's callback to allow extra products + ExportProductList extraProducts; + ScriptBuildingNotificationBus::BroadcastResult(extraProducts, &ScriptBuildingNotificationBus::Events::OnPrepareForExport, + context.GetScene(), + context.GetOutputDirectory(), + context.GetPlatformIdentifier(), + context.GetProductList() + ); - auto& sceneManifest = scene.GetManifest(); - auto view = Containers::MakeDerivedFilterView(sceneManifest.GetValueStorage()); - for (const auto& scriptItem : view) + // add new products + for (const auto& product : extraProducts.GetProducts()) + { + context.GetProductList().AddProduct( + product.m_filename, + product.m_id, + product.m_assetType, + product.m_lod, + product.m_subId, + product.m_dependencyFlags); + } + }; + + if (LoadPython(context.GetScene())) + { + EditorPythonConsoleNotificationHandler logger; + m_editorPythonEventsInterface->ExecuteWithLock(executeCallback); + } + + return true; + } + + void ScriptProcessorRuleBehavior::Reflect(ReflectContext* context) + { + ScriptBuildingNotificationBusHandler::Reflect(context); + + SerializeContext* serializeContext = azrtti_cast(context); + if (serializeContext) + { + serializeContext->Class()->Version(1); + } + } + + Events::ProcessingResult ScriptProcessorRuleBehavior::UpdateManifest( + Containers::Scene& scene, + Events::AssetImportRequest::ManifestAction action, + [[maybe_unused]] Events::AssetImportRequest::RequestingApplication requester) + { + using namespace AzToolsFramework; + + if (action != ManifestAction::Update) + { + return Events::ProcessingResult::Ignored; + } + + if (LoadPython(scene)) + { + AZStd::string manifestUpdate; + auto executeCallback = [this, &scene, &manifestUpdate]() + { + EditorPythonRunnerRequestBus::Broadcast(&EditorPythonRunnerRequestBus::Events::ExecuteByFilename, + m_scriptFilename.c_str()); + + ScriptBuildingNotificationBus::BroadcastResult(manifestUpdate, &ScriptBuildingNotificationBus::Events::OnUpdateManifest, + scene); + }; + + EditorPythonConsoleNotificationHandler logger; + m_editorPythonEventsInterface->ExecuteWithLock(executeCallback); + + // attempt to load the manifest string back to a JSON-scene-manifest + auto sceneManifestLoader = AZStd::make_unique(); + auto loadOutcome = sceneManifestLoader->LoadFromString(manifestUpdate); + if (loadOutcome.IsSuccess()) + { + scene.GetManifest().Clear(); + for (size_t entryIndex = 0; entryIndex < sceneManifestLoader->GetEntryCount(); ++entryIndex) { - AZ::IO::FixedMaxPath scriptFilename(scriptItem.GetScriptFilename()); - if (scriptFilename.empty()) - { - AZ_Warning("scene", false, "Skipping an empty script filename in (%s)", scene.GetManifestFilename().c_str()); - continue; - } - - // check for file exist via absolute path - if (!IO::FileIOBase::GetInstance()->Exists(scriptFilename.c_str())) - { - // check for script in the project folder - AZ::IO::FixedMaxPath projectScriptPath = projectPath / scriptFilename; - if (!IO::FileIOBase::GetInstance()->Exists(projectScriptPath.c_str())) - { - AZ_Warning("scene", false, "Skipping a missing script (%s) in manifest file (%s)", - scriptFilename.c_str(), - scene.GetManifestFilename().c_str()); - - continue; - } - scriptFilename = AZStd::move(projectScriptPath); - } - - // lazy load the Python interface - if (!m_editorPythonEventsInterface) - { - m_editorPythonEventsInterface = AZ::Interface::Get(); - const bool silenceWarnings = true; - m_editorPythonEventsInterface->StartPython(silenceWarnings); - } - - if (!m_editorPythonEventsInterface && !scriptFilename.empty()) - { - AZ_Warning("scene", false, - "The scene manifest (%s) attempted to use script(%s) but Python is not enabled;" - "please add the EditorPythonBinding gem & PythonAssetBuilder gem to your project.", - scene.GetManifestFilename().c_str(), scriptFilename.c_str()); - - return Events::ProcessingResult::Ignored; - } - - AZStd::string manifestUpdate; - auto executeCallback = [&scene, &scriptFilename, &manifestUpdate]() - { - EditorPythonRunnerRequestBus::Broadcast( - &EditorPythonRunnerRequestBus::Events::ExecuteByFilename, - scriptFilename.c_str()); - - ScriptBuildingNotificationBus::BroadcastResult( - manifestUpdate, - &ScriptBuildingNotificationBus::Events::OnUpdateManifest, - scene); - }; - EditorPythonConsoleNotificationHandler logger; - m_editorPythonEventsInterface->ExecuteWithLock(executeCallback); - - // attempt to load the manifest string back to a JSON-scene-manifest - auto sceneManifestLoader = AZStd::make_unique(); - auto loadOutcome = sceneManifestLoader->LoadFromString(manifestUpdate); - if (loadOutcome.IsSuccess()) - { - sceneManifest.Clear(); - for (size_t entryIndex = 0; entryIndex < sceneManifestLoader->GetEntryCount(); ++entryIndex) - { - sceneManifest.AddEntry(sceneManifestLoader->GetValue(entryIndex)); - } - return Events::ProcessingResult::Success; - } + scene.GetManifest().AddEntry(sceneManifestLoader->GetValue(entryIndex)); } - return Events::ProcessingResult::Ignored; + return Events::ProcessingResult::Success; } + } + return Events::ProcessingResult::Ignored; + } - } // namespace Behaviors - } // namespace SceneAPI } // namespace AZ diff --git a/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.h b/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.h index da11614459..9dd1f5b970 100644 --- a/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.h +++ b/Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.h @@ -11,40 +11,56 @@ #include #include #include +#include +#include namespace AzToolsFramework { class EditorPythonEventsInterface; } -namespace AZ +namespace AZ::SceneAPI::Events { - namespace SceneAPI + class PreExportEventContext; +} + +namespace AZ::SceneAPI::Containers +{ + class Scene; +} + +namespace AZ::SceneAPI::Behaviors +{ + class SCENE_DATA_CLASS ScriptProcessorRuleBehavior + : public SceneCore::BehaviorComponent + , public Events::AssetImportRequestBus::Handler { - namespace Behaviors - { - class SCENE_DATA_CLASS ScriptProcessorRuleBehavior - : public SceneCore::BehaviorComponent - , public Events::AssetImportRequestBus::Handler - { - public: - AZ_COMPONENT(ScriptProcessorRuleBehavior, "{24054E73-1B92-43B0-AC13-174B2F0E3F66}", SceneCore::BehaviorComponent); - - ~ScriptProcessorRuleBehavior() override = default; - - SCENE_DATA_API void Activate() override; - SCENE_DATA_API void Deactivate() override; - static void Reflect(ReflectContext* context); - - // AssetImportRequestBus::Handler - SCENE_DATA_API Events::ProcessingResult UpdateManifest( - Containers::Scene& scene, - ManifestAction action, - RequestingApplication requester) override; - - private: - AzToolsFramework::EditorPythonEventsInterface* m_editorPythonEventsInterface = nullptr; - }; - } // namespace SceneData - } // namespace SceneAPI -} // namespace AZ + public: + AZ_COMPONENT(ScriptProcessorRuleBehavior, "{24054E73-1B92-43B0-AC13-174B2F0E3F66}", SceneCore::BehaviorComponent); + + ~ScriptProcessorRuleBehavior() override = default; + + SCENE_DATA_API void Activate() override; + SCENE_DATA_API void Deactivate() override; + static void Reflect(ReflectContext* context); + + // AssetImportRequestBus::Handler + SCENE_DATA_API Events::ProcessingResult UpdateManifest( + Containers::Scene& scene, + ManifestAction action, + RequestingApplication requester) override; + + + protected: + bool LoadPython(const AZ::SceneAPI::Containers::Scene& scene); + void UnloadPython(); + bool DoPrepareForExport(Events::PreExportEventContext& context); + + private: + AzToolsFramework::EditorPythonEventsInterface* m_editorPythonEventsInterface = nullptr; + AZStd::string m_scriptFilename; + + struct ExportEventHandler; + AZStd::shared_ptr m_exportEventHandler; + }; +} // namespace AZ::SceneAPI::Behaviors diff --git a/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp b/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp index a2241b9953..a9e344f4ee 100644 --- a/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp +++ b/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp @@ -237,8 +237,8 @@ namespace EditorPythonBindings { ec->Class("PythonSystemComponent", "The Python interpreter") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("System")) - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("System")) + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ; } } @@ -284,10 +284,10 @@ namespace EditorPythonBindings ReleaseFunction m_releaseFunction; }; ReleaseInitalizeWaiterScope scope([this]() - { - m_initalizeWaiter.release(m_initalizeWaiterCount); - m_initalizeWaiterCount = 0; - }); + { + m_initalizeWaiter.release(m_initalizeWaiterCount); + m_initalizeWaiterCount = 0; + }); if (Py_IsInitialized()) { @@ -327,6 +327,11 @@ namespace EditorPythonBindings return result; } + bool PythonSystemComponent::IsPythonActive() + { + return Py_IsInitialized() != 0; + } + void PythonSystemComponent::WaitForInitialization() { m_initalizeWaiterCount++; diff --git a/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.h b/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.h index 82f44e674d..8e616ff85b 100644 --- a/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.h +++ b/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.h @@ -44,6 +44,7 @@ namespace EditorPythonBindings // AzToolsFramework::EditorPythonEventsInterface bool StartPython(bool silenceWarnings = false) override; bool StopPython(bool silenceWarnings = false) override; + bool IsPythonActive() override; void WaitForInitialization() override; void ExecuteWithLock(AZStd::function executionCallback) override; //////////////////////////////////////////////////////////////////////// From e32b7a7c870e87f1524c6255a302ed596b411d66 Mon Sep 17 00:00:00 2001 From: rgba16f <82187279+rgba16f@users.noreply.github.com> Date: Wed, 14 Jul 2021 15:14:42 -0500 Subject: [PATCH 37/53] Mac m1 fixes (#2150) * Update the Mac Editor plist application bundle identifier to be different than Lumberyard Fix the editor to have runtime dependencies on the scene modules. Signed-off-by: rgba16f <82187279+rgba16f@users.noreply.github.com> * Fix Metal RHI calling unsupported timestamp query api on M1 Macs. Add Query for Timestamps supported on device initialization. Signed-off-by: rgba16f <82187279+rgba16f@users.noreply.github.com> * Remove AZ::Scene* runtime dependencies from EmotionFX gem and add AZ::SceneUI as a runtime dependency of SceneProcessing::Editor module. Signed-off-by: rgba16f <82187279+rgba16f@users.noreply.github.com> --- Code/Editor/Platform/Mac/gui_info.plist | 2 +- .../Plugins/EditorCommon/CMakeLists.txt | 4 ++++ .../Metal/Code/Source/RHI/CommandListBase.cpp | 23 +++++++++++++++--- .../Metal/Code/Source/RHI/CommandListBase.h | 2 ++ .../Atom/RHI/Metal/Code/Source/RHI/Device.cpp | 24 +++++++++++++++---- Gems/SceneProcessing/Code/CMakeLists.txt | 1 + 6 files changed, 47 insertions(+), 9 deletions(-) diff --git a/Code/Editor/Platform/Mac/gui_info.plist b/Code/Editor/Platform/Mac/gui_info.plist index 0ec7b59e98..5b5f94e977 100644 --- a/Code/Editor/Platform/Mac/gui_info.plist +++ b/Code/Editor/Platform/Mac/gui_info.plist @@ -5,7 +5,7 @@ CFBundleExecutable Editor CFBundleIdentifier - com.Amazon.Lumberyard.Editor + org.O3DE.Editor CFBundlePackageType APPL CFBundleSignature diff --git a/Code/Editor/Plugins/EditorCommon/CMakeLists.txt b/Code/Editor/Plugins/EditorCommon/CMakeLists.txt index 96d9cce5b7..048f77cd0c 100644 --- a/Code/Editor/Plugins/EditorCommon/CMakeLists.txt +++ b/Code/Editor/Plugins/EditorCommon/CMakeLists.txt @@ -46,4 +46,8 @@ ly_add_target( AZ::AzCore AZ::AzToolsFramework AZ::AzQtComponents + RUNTIME_DEPENDENCIES + AZ::AzCore + AZ::AzToolsFramework + AZ::AzQtComponents ) diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.cpp index 675a593bc8..9df5f3362d 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.cpp @@ -30,6 +30,7 @@ namespace AZ { AZ_UNUSED(device); m_hardwareQueueClass = hardwareQueueClass; + m_supportsInterDrawTimestamps = AZ::RHI::QueryTypeFlags::Timestamp == (device->GetFeatures().m_queryTypesMask[static_cast(hardwareQueueClass)] & AZ::RHI::QueryTypeFlags::Timestamp); } void CommandListBase::Reset() @@ -64,7 +65,10 @@ namespace AZ [m_encoder endEncoding]; m_encoder = nil; #if AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING - m_timeStampQueue.clear(); + if (m_supportsInterDrawTimestamps) + { + m_timeStampQueue.clear(); + } #endif } } @@ -144,9 +148,12 @@ namespace AZ m_isEncoded = true; #if AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING - for(auto& timeStamp: m_timeStampQueue) + if (m_supportsInterDrawTimestamps) { - SampleCounters(timeStamp.m_counterSampleBuffer, timeStamp.m_timeStampIndex); + for(auto& timeStamp: m_timeStampQueue) + { + SampleCounters(timeStamp.m_counterSampleBuffer, timeStamp.m_timeStampIndex); + } } #endif } @@ -195,6 +202,11 @@ namespace AZ #if AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING void CommandListBase::SampleCounters(id counterSampleBuffer, uint32_t sampleIndex) { + if (!m_supportsInterDrawTimestamps) + { + return; + } + AZ_Assert(sampleIndex >= 0, "Invalid sample index"); //useBarrier - Inserting a barrier ensures that encoded work is complete before the GPU samples the hardware counters. //If it is true there is a performance penalty but you will get consistent results @@ -231,6 +243,11 @@ namespace AZ void CommandListBase::SamplePassCounters(id counterSampleBuffer, uint32_t sampleIndex) { + if (!m_supportsInterDrawTimestamps) + { + return; + } + if(m_encoder == nil) { //Queue the query to be activated upon encoder creation. Applies to timestamp queries diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.h b/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.h index 70678aed01..a344222e63 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.h +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/CommandListBase.h @@ -101,6 +101,8 @@ namespace AZ const AZStd::set>* m_residentHeaps = nullptr; + bool m_supportsInterDrawTimestamps = AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING; // iOS/TVOS = false, MacOS = defaults to true + #if AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING struct TimeStampData { diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp index 5e23353b65..0da2ea6aaa 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp @@ -328,14 +328,28 @@ namespace AZ m_features.m_indirectDrawSupport = false; RHI::QueryTypeFlags counterSamplingFlags = RHI::QueryTypeFlags::None; - -#if AZ_TRAIT_ATOM_METAL_COUNTER_SAMPLING - counterSamplingFlags |= (RHI::QueryTypeFlags::Timestamp | RHI::QueryTypeFlags::PipelineStatistics); - m_features.m_queryTypesMask[static_cast(RHI::HardwareQueueClass::Copy)] = RHI::QueryTypeFlags::Timestamp; + + bool supportsInterDrawTimestamps = true; +#if defined(__IPHONE_14_0) || defined(__MAC_11_0) || defined(__TVOS_14_0) + if (@available(macOS 11.0, iOS 14, tvOS 14, *)) + { + supportsInterDrawTimestamps = [m_metalDevice supportsCounterSampling:MTLCounterSamplingPointAtDrawBoundary]; + } + else #endif + { + supportsInterDrawTimestamps = ![m_metalDevice.name containsString:@"Apple"]; // Apple GPU's don't support inter draw timestamps at the M1/A14 generation + } + + if (supportsInterDrawTimestamps) + { + counterSamplingFlags |= (RHI::QueryTypeFlags::Timestamp | RHI::QueryTypeFlags::PipelineStatistics); + m_features.m_queryTypesMask[static_cast(RHI::HardwareQueueClass::Copy)] = RHI::QueryTypeFlags::Timestamp; + } + m_features.m_queryTypesMask[static_cast(RHI::HardwareQueueClass::Graphics)] = RHI::QueryTypeFlags::Occlusion | counterSamplingFlags; //Compute queue can do gfx work - m_features.m_queryTypesMask[static_cast(RHI::HardwareQueueClass::Compute)] = RHI::QueryTypeFlags::Occlusion |counterSamplingFlags; + m_features.m_queryTypesMask[static_cast(RHI::HardwareQueueClass::Compute)] = RHI::QueryTypeFlags::Occlusion | counterSamplingFlags; m_features.m_occlusionQueryPrecise = true; //Values taken from https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf diff --git a/Gems/SceneProcessing/Code/CMakeLists.txt b/Gems/SceneProcessing/Code/CMakeLists.txt index 9aa5bc6763..b33e157e51 100644 --- a/Gems/SceneProcessing/Code/CMakeLists.txt +++ b/Gems/SceneProcessing/Code/CMakeLists.txt @@ -61,6 +61,7 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) RUNTIME_DEPENDENCIES AZ::SceneCore AZ::SceneData + AZ::SceneUI ) # the SceneProcessing.Editor module above is only used in Builders and Tools. ly_create_alias(NAME SceneProcessing.Builders NAMESPACE Gem TARGETS Gem::SceneProcessing.Editor) From 32a27966202fbc18e74d760775602f2b28d318b7 Mon Sep 17 00:00:00 2001 From: galibzon <66021303+galibzon@users.noreply.github.com> Date: Wed, 14 Jul 2021 15:38:08 -0500 Subject: [PATCH 38/53] [ATOM-15978] ShaderVariantAssetBuilder needs to fill up ShaderPlatformInterface::m_srgLayouts for Metal (#2156) ShaderVariantAssetBuilder builds SRG Layout data only for Metal. Signed-off-by: garrieta --- .../AzslShaderBuilderSystemComponent.cpp | 2 +- .../Editor/ShaderVariantAssetBuilder.cpp | 135 ++++++++++++++++++ .../Atom/RHI.Edit/ShaderPlatformInterface.h | 6 + .../RHI.Edit/ShaderCompilerArguments.cpp | 8 +- .../RHI.Builders/ShaderPlatformInterface.h | 2 + 5 files changed, 151 insertions(+), 2 deletions(-) diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslShaderBuilderSystemComponent.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslShaderBuilderSystemComponent.cpp index afa11d8e16..f6b99cac12 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslShaderBuilderSystemComponent.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslShaderBuilderSystemComponent.cpp @@ -95,7 +95,7 @@ namespace AZ shaderVariantAssetBuilderDescriptor.m_name = "Shader Variant Asset Builder"; // Both "Shader Variant Asset Builder" and "Shader Asset Builder" produce ShaderVariantAsset products. If you update // ShaderVariantAsset you will need to update BOTH version numbers, not just "Shader Variant Asset Builder". - shaderVariantAssetBuilderDescriptor.m_version = 23; // ATOM-15472 + shaderVariantAssetBuilderDescriptor.m_version = 24; // ATOM-15978 shaderVariantAssetBuilderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string::format("*.%s", RPI::ShaderVariantListSourceData::Extension), AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); shaderVariantAssetBuilderDescriptor.m_busId = azrtti_typeid(); shaderVariantAssetBuilderDescriptor.m_createJobFunction = AZStd::bind(&ShaderVariantAssetBuilder::CreateJobs, &m_shaderVariantAssetBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2); diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp index 7be98ab056..010778575e 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp @@ -48,6 +48,7 @@ #include "ShaderAssetBuilder.h" #include "ShaderBuilderUtility.h" +#include "SrgLayoutUtility.h" #include "AzslData.h" #include "AzslCompiler.h" #include @@ -520,6 +521,96 @@ namespace AZ return; } } + + static bool LoadSrgLayoutListFromShaderAssetBuilder( + const RHI::ShaderPlatformInterface* shaderPlatformInterface, + const AssetBuilderSDK::PlatformInfo& platformInfo, + const AzslCompiler& azslCompiler, const AZStd::string& shaderSourceFileFullPath, + const RPI::SupervariantIndex supervariantIndex, + const bool platformUsesRegisterSpaces, + RPI::ShaderResourceGroupLayoutList& srgLayoutList, + RootConstantData& rootConstantData) + { + auto srgJsonPathOutcome = ShaderBuilderUtility::ObtainBuildArtifactPathFromShaderAssetBuilder( + shaderPlatformInterface->GetAPIUniqueIndex(), platformInfo.m_identifier, shaderSourceFileFullPath, supervariantIndex.GetIndex(), AZ::RPI::ShaderAssetSubId::SrgJson); + if (!srgJsonPathOutcome.IsSuccess()) + { + AZ_Error(ShaderVariantAssetBuilderName, false, "%s", srgJsonPathOutcome.GetError().c_str()); + return false; + } + + auto srgJsonPath = srgJsonPathOutcome.TakeValue(); + auto jsonOutcome = JsonSerializationUtils::ReadJsonFile(srgJsonPath); + if (!jsonOutcome.IsSuccess()) + { + AZ_Error(ShaderVariantAssetBuilderName, false, "%s", jsonOutcome.GetError().c_str()); + return false; + } + SrgDataContainer srgData; + if (!azslCompiler.ParseSrgPopulateSrgData(jsonOutcome.GetValue(), srgData)) + { + AZ_Error(ShaderVariantAssetBuilderName, false, "Failed to parse srg data"); + return false; + } + // Add all Shader Resource Group Assets that were defined in the shader code to the shader asset + if (!SrgLayoutUtility::LoadShaderResourceGroupLayouts(ShaderVariantAssetBuilderName, srgData, platformUsesRegisterSpaces, srgLayoutList)) + { + AZ_Error(ShaderVariantAssetBuilderName, false, "Failed to load ShaderResourceGroupLayouts"); + return false; + } + + for (auto srgLayout : srgLayoutList) + { + if (!srgLayout->Finalize()) + { + AZ_Error(ShaderVariantAssetBuilderName, false, + "Failed to finalize SrgLayout %s", srgLayout->GetName().GetCStr()); + return false; + } + } + + // Access the root constants reflection + if (!azslCompiler.ParseSrgPopulateRootConstantData( + jsonOutcome.GetValue(), + rootConstantData)) // consuming data from --srg ("InlineConstantBuffer" subjson section) + { + AZ_Error(ShaderVariantAssetBuilderName, false, "Failed to obtain root constant data reflection"); + return false; + } + + return true; + } + + static bool LoadBindingDependenciesFromShaderAssetBuilder( + const RHI::ShaderPlatformInterface* shaderPlatformInterface, + const AssetBuilderSDK::PlatformInfo& platformInfo, + const AzslCompiler& azslCompiler, const AZStd::string& shaderSourceFileFullPath, + const RPI::SupervariantIndex supervariantIndex, + BindingDependencies& bindingDependencies) + { + auto bindingsJsonPathOutcome = ShaderBuilderUtility::ObtainBuildArtifactPathFromShaderAssetBuilder( + shaderPlatformInterface->GetAPIUniqueIndex(), platformInfo.m_identifier, shaderSourceFileFullPath, supervariantIndex.GetIndex(), AZ::RPI::ShaderAssetSubId::BindingdepJson); + if (!bindingsJsonPathOutcome.IsSuccess()) + { + AZ_Error(ShaderVariantAssetBuilderName, false, "%s", bindingsJsonPathOutcome.GetError().c_str()); + return false; + } + + auto bindingsJsonPath = bindingsJsonPathOutcome.TakeValue(); + auto jsonOutcome = JsonSerializationUtils::ReadJsonFile(bindingsJsonPath); + if (!jsonOutcome.IsSuccess()) + { + AZ_Error(ShaderVariantAssetBuilderName, false, "%s", jsonOutcome.GetError().c_str()); + return false; + } + if (!azslCompiler.ParseBindingdepPopulateBindingDependencies(jsonOutcome.GetValue(), bindingDependencies)) + { + AZ_Error(ShaderVariantAssetBuilderName, false, "Failed to parse binding dependencies data"); + return false; + } + + return true; + } // Returns the content of the hlsl file for the given supervariant as produced by ShaderAsssetBuilder. @@ -773,6 +864,50 @@ namespace AZ response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed; return; } + + //! It is important to keep this refcounted pointer outside of the if block to prevent it from being destroyed. + RHI::Ptr pipelineLayoutDescriptor; + if (shaderPlatformInterface->VariantCompilationRequiresSrgLayoutData()) + { + AZStd::string azslcCompilerParameters = + shaderPlatformInterface->GetAzslCompilerParameters(buildOptions.m_compilerArguments); + const bool platformUsesRegisterSpaces = + (AzFramework::StringFunc::Find(azslcCompilerParameters, "--use-spaces") != AZStd::string::npos); + + RPI::ShaderResourceGroupLayoutList srgLayoutList; + RootConstantData rootConstantData; + if (!LoadSrgLayoutListFromShaderAssetBuilder( + shaderPlatformInterface, request.m_platformInfo, azslc, shaderSourceFileFullPath, supervariantIndex, + platformUsesRegisterSpaces, + srgLayoutList, + rootConstantData)) + { + response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed; + return; + } + + BindingDependencies bindingDependencies; + if (!LoadBindingDependenciesFromShaderAssetBuilder( + shaderPlatformInterface, request.m_platformInfo, azslc, shaderSourceFileFullPath, supervariantIndex, + bindingDependencies)) + { + response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed; + return; + } + + pipelineLayoutDescriptor = + ShaderBuilderUtility::BuildPipelineLayoutDescriptorForApi( + ShaderVariantAssetBuilderName, srgLayoutList, shaderEntryPoints, buildOptions.m_compilerArguments, rootConstantData, + shaderPlatformInterface, bindingDependencies); + if (!pipelineLayoutDescriptor) + { + AZ_Error( + ShaderVariantAssetBuilderName, false, "Failed to build pipeline layout descriptor for api=[%s]", + shaderPlatformInterface->GetAPIName().GetCStr()); + response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed; + return; + } + } // Setup the shader variant creation context: ShaderVariantCreationContext shaderVariantCreationContext = diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Edit/ShaderPlatformInterface.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Edit/ShaderPlatformInterface.h index d83fbf2267..f7db5f865b 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Edit/ShaderPlatformInterface.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Edit/ShaderPlatformInterface.h @@ -144,6 +144,12 @@ namespace AZ const ShaderResourceGroupInfoList& srgInfoList, const RootConstantsInfo& rootConstantsInfo, const ShaderCompilerArguments& shaderCompilerArguments) = 0; + + //! In general, shader compilation doesn't require SRG Layout data, but RHIs like + //! Metal don't do well if unused resources (descriptors) are not bound. If this function returns TRUE + //! the ShaderVariantAssetBuilder will invoke BuildPipelineLayoutDescriptor() so the RHI gets the chance to + //! build SRG Layout data which will be useful when compiling MetalISL to Metal byte code. + virtual bool VariantCompilationRequiresSrgLayoutData() const { return false; } //! See AZ::RHI::Factory::GetAPIUniqueIndex() for details. //! See AZ::RHI::Limits::APIType::PerPlatformApiUniqueIndexMax. diff --git a/Gems/Atom/RHI/Code/Source/RHI.Edit/ShaderCompilerArguments.cpp b/Gems/Atom/RHI/Code/Source/RHI.Edit/ShaderCompilerArguments.cpp index 0801101178..2f648acc05 100644 --- a/Gems/Atom/RHI/Code/Source/RHI.Edit/ShaderCompilerArguments.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI.Edit/ShaderCompilerArguments.cpp @@ -159,7 +159,13 @@ namespace AZ arguments += " -Zi"; // Generate debug information arguments += " -Zss"; // Compute Shader Hash considering source information } - arguments += " " + m_dxcAdditionalFreeArguments; + // strip spaces at both sides + AZStd::string dxcAdditionalFreeArguments = m_dxcAdditionalFreeArguments; + AzFramework::StringFunc::TrimWhiteSpace(dxcAdditionalFreeArguments, true, true); + if (!dxcAdditionalFreeArguments.empty()) + { + arguments += " " + dxcAdditionalFreeArguments; + } return arguments; } } diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI.Builders/ShaderPlatformInterface.h b/Gems/Atom/RHI/Metal/Code/Source/RHI.Builders/ShaderPlatformInterface.h index 935d2e6471..0be02053cd 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI.Builders/ShaderPlatformInterface.h +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI.Builders/ShaderPlatformInterface.h @@ -40,6 +40,8 @@ namespace AZ const ShaderResourceGroupInfoList& srgInfoList, const RootConstantsInfo& rootConstantsInfo, const RHI::ShaderCompilerArguments& shaderCompilerArguments) override; + + bool VariantCompilationRequiresSrgLayoutData() const override { return true; } bool CompilePlatformInternal( const AssetBuilderSDK::PlatformInfo& platform, From 24831b1970bed10c56f00b9d32f7c62ffa50d7ee Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Wed, 14 Jul 2021 14:54:57 -0700 Subject: [PATCH 39/53] Code review changes Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- .../PlatformAddressedAssetCatalogTests.cpp | 2 +- .../Tests/Prefab/PrefabInstantiateTests.cpp | 2 +- .../Tests/Prefab/PrefabLoadTemplateTests.cpp | 18 +++++++++--------- .../Tests/Prefab/PrefabTestDomUtils.cpp | 12 ++++-------- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp b/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp index 2ac66564df..29b48a1f31 100644 --- a/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp @@ -248,7 +248,7 @@ namespace UnitTest AZ_TEST_START_TRACE_SUPPRESSION; auto* mockCatalog = new ::testing::NiceMock(AzFramework::PlatformId::ANDROID_ID); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; + AZ_TEST_STOP_TRACE_SUPPRESSION(1); AZStd::unique_ptr< ::testing::NiceMock> catalogHolder; catalogHolder.reset(mockCatalog); diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstantiateTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstantiateTests.cpp index 81d44d7426..b0fd167cc0 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstantiateTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabInstantiateTests.cpp @@ -15,7 +15,7 @@ namespace UnitTest { AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_FALSE(m_prefabSystemComponent->InstantiatePrefab(AzToolsFramework::Prefab::InvalidTemplateId)); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; + AZ_TEST_STOP_TRACE_SUPPRESSION(1); } TEST_F(PrefabInstantiateTest, PrefabInstantiate_NoNestingTemplate_InstantiateSucceeds) diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabLoadTemplateTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabLoadTemplateTests.cpp index db7640916d..bf47e57206 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabLoadTemplateTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabLoadTemplateTests.cpp @@ -71,7 +71,7 @@ namespace UnitTest AZ_TEST_START_TRACE_SUPPRESSION; templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(templateData.m_filePath); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; + AZ_TEST_STOP_TRACE_SUPPRESSION(3); templateData.m_isLoadedWithErrors = true; PrefabTestDataUtils::ValidateTemplateLoad(templateData); @@ -119,7 +119,7 @@ namespace UnitTest // Load target and source Templates and get their Ids. AZ_TEST_START_TRACE_SUPPRESSION; targetTemplateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(targetTemplateData.m_filePath); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; + AZ_TEST_STOP_TRACE_SUPPRESSION(4); sourceTemplateData.m_id = m_prefabSystemComponent->GetTemplateIdFromFilePath(sourceTemplateData.m_filePath); // Because of cyclical dependency, the two Templates should be loaded with errors. @@ -150,7 +150,7 @@ namespace UnitTest AZ_TEST_START_TRACE_SUPPRESSION; templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(templateData.m_filePath); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; + AZ_TEST_STOP_TRACE_SUPPRESSION(2); PrefabTestDataUtils::ValidateTemplateLoad(templateData); } @@ -169,7 +169,7 @@ namespace UnitTest AZ_TEST_START_TRACE_SUPPRESSION; templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(templateData.m_filePath); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; + AZ_TEST_STOP_TRACE_SUPPRESSION(2); PrefabTestDataUtils::ValidateTemplateLoad(templateData); } @@ -193,7 +193,7 @@ namespace UnitTest AZ_TEST_START_TRACE_SUPPRESSION; templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromFile(templateData.m_filePath); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; + AZ_TEST_STOP_TRACE_SUPPRESSION(3); PrefabTestDataUtils::ValidateTemplateLoad(templateData); } @@ -292,7 +292,7 @@ namespace UnitTest AZ_TEST_START_TRACE_SUPPRESSION; TemplateId templateId = m_prefabLoaderInterface->LoadTemplateFromFile(pathToCorruptedPrefab); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; + AZ_TEST_STOP_TRACE_SUPPRESSION(1); EXPECT_EQ(templateId, AzToolsFramework::Prefab::InvalidTemplateId); } @@ -304,7 +304,7 @@ namespace UnitTest AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_EQ(m_prefabLoaderInterface->LoadTemplateFromString(emptyPrefabDomStr, "|?<>"), AzToolsFramework::Prefab::InvalidTemplateId); EXPECT_EQ(m_prefabLoaderInterface->LoadTemplateFromString(emptyPrefabDomStr, "notAFile/"), AzToolsFramework::Prefab::InvalidTemplateId); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; + AZ_TEST_STOP_TRACE_SUPPRESSION(2); } TEST_F(PrefabLoadTemplateTest, LoadTemplate_LoadFromString_LoadsEmptyPrefab) @@ -336,7 +336,7 @@ namespace UnitTest templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromString( selfDependentPrefabStr, templateData.m_filePath); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; + AZ_TEST_STOP_TRACE_SUPPRESSION(3); templateData.m_isLoadedWithErrors = true; @@ -348,7 +348,7 @@ namespace UnitTest AZStd::string corruptPrefab = "{ Corrupted PrefabDom"; AZ_TEST_START_TRACE_SUPPRESSION; TemplateId templateId = m_prefabLoaderInterface->LoadTemplateFromString(corruptPrefab); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; + AZ_TEST_STOP_TRACE_SUPPRESSION(1); EXPECT_EQ(templateId, AzToolsFramework::Prefab::InvalidTemplateId); } } diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestDomUtils.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestDomUtils.cpp index 413e3ea0b4..6e836e4d44 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestDomUtils.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabTestDomUtils.cpp @@ -169,14 +169,10 @@ namespace UnitTest if (expectedNestedInstanceDomInstances->get().IsArray()) { ASSERT_TRUE(actualNestedInstanceDomInstances->get().IsArray()); - const size_t arraySize = expectedNestedInstanceDomInstances->get().GetArray().Size(); - for(size_t i = 0; i < arraySize; ++i) - { - ComparePrefabDoms( - expectedNestedInstanceDomInstances->get().GetArray()[i], - actualNestedInstanceDomInstances->get().GetArray()[i], - shouldCompareLinkIds, shouldCompareContainerEntities); - } + const size_t expectedArraySize = expectedNestedInstanceDomInstances->get().GetArray().Size(); + EXPECT_EQ(0, expectedArraySize); + const size_t actualArraySize = actualNestedInstanceDomInstances->get().GetArray().Size(); + EXPECT_EQ(0, actualArraySize); } if (expectedNestedInstanceDomInstances->get().IsObject()) { From 59e9f108537b84d6a37718fc8a637892a546b8dc Mon Sep 17 00:00:00 2001 From: michabr <82236305+michabr@users.noreply.github.com> Date: Wed, 14 Jul 2021 15:57:02 -0700 Subject: [PATCH 40/53] Split LyShine .Editor target to .Tools and .Builders (#2161) * Split LyShine .Editor target to .Tools and .Builders Signed-off-by: abrmich * Fix compile error for Tests target Signed-off-by: abrmich --- Gems/LyShine/Code/CMakeLists.txt | 66 +++++++++++++++++-- Gems/LyShine/Code/Source/LyShineModule.cpp | 12 ++-- .../Code/lyshine_common_module_files.cmake | 2 + Gems/LyShine/Code/lyshine_static_files.cmake | 2 - 4 files changed, 68 insertions(+), 14 deletions(-) diff --git a/Gems/LyShine/Code/CMakeLists.txt b/Gems/LyShine/Code/CMakeLists.txt index fe5e2e77df..905228e414 100644 --- a/Gems/LyShine/Code/CMakeLists.txt +++ b/Gems/LyShine/Code/CMakeLists.txt @@ -63,7 +63,6 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) AUTORCC FILES_CMAKE lyshine_uicanvaseditor_files.cmake - lyshine_editor_builder_files.cmake INCLUDE_DIRECTORIES PRIVATE . @@ -78,7 +77,6 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) 3rdParty::Qt::Widgets AZ::AzCore AZ::AzToolsFramework - AZ::AssetBuilderSDK Legacy::EditorCommon Legacy::EditorCore Gem::LyShine.Static @@ -98,7 +96,6 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) ly_add_target( NAME LyShine.Editor GEM_MODULE - NAMESPACE Gem FILES_CMAKE lyshine_common_module_files.cmake @@ -115,17 +112,72 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) BUILD_DEPENDENCIES PRIVATE Legacy::CryCommon - AZ::AssetBuilderSDK + AZ::AzToolsFramework Gem::LyShine.Editor.Static Gem::LmbrCentral.Editor Gem::TextureAtlas.Editor RUNTIME_DEPENDENCIES Gem::LmbrCentral.Editor Gem::TextureAtlas.Editor -) + ) + + # by naming this target LyShine.Builders it ensures that it is loaded + # in any pipeline tools (Like Asset Processor, AssetBuilder, etc) + ly_add_target( + NAME LyShine.Builders.Static STATIC + NAMESPACE Gem + FILES_CMAKE + lyshine_editor_builder_files.cmake + INCLUDE_DIRECTORIES + PRIVATE + . + Source + PUBLIC + Include + BUILD_DEPENDENCIES + PRIVATE + AZ::AzCore + AZ::AzToolsFramework + AZ::AssetBuilderSDK + Gem::LyShine.Static + Legacy::CryCommon + Gem::LmbrCentral.Editor + Gem::TextureAtlas.Editor + Gem::AtomToolsFramework.Static + Gem::AtomToolsFramework.Editor + ${additional_dependencies} + PUBLIC + Gem::Atom_RPI.Public + Gem::Atom_Utils.Static + Gem::Atom_Bootstrap.Headers + ) + + ly_add_target( + NAME LyShine.Builders GEM_MODULE + NAMESPACE Gem + OUTPUT_NAME Gem.LyShine.Builders + FILES_CMAKE + lyshine_common_module_files.cmake + COMPILE_DEFINITIONS + PRIVATE + LYSHINE_BUILDER + INCLUDE_DIRECTORIES + PRIVATE + . + Source + Editor + PUBLIC + Include + BUILD_DEPENDENCIES + PRIVATE + Legacy::CryCommon + AZ::AssetBuilderSDK + Gem::LyShine.Builders.Static + Gem::LmbrCentral.Editor + Gem::TextureAtlas.Editor + ) # by default, load the above "Gem::LyShine.Editor" module in dev tools: - ly_create_alias(NAME LyShine.Builders NAMESPACE Gem TARGETS Gem::LyShine.Editor) ly_create_alias(NAME LyShine.Tools NAMESPACE Gem TARGETS Gem::LyShine.Editor) endif() @@ -169,6 +221,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) COMPILE_DEFINITIONS PRIVATE LYSHINE_EDITOR + LYSHINE_BUILDER INCLUDE_DIRECTORIES PRIVATE Tests @@ -182,6 +235,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) Legacy::CryCommon AZ::AssetBuilderSDK Gem::LyShine.Editor.Static + Gem::LyShine.Builders.Static Gem::LmbrCentral.Editor Gem::TextureAtlas RUNTIME_DEPENDENCIES diff --git a/Gems/LyShine/Code/Source/LyShineModule.cpp b/Gems/LyShine/Code/Source/LyShineModule.cpp index 011bb9f203..64ce61b07a 100644 --- a/Gems/LyShine/Code/Source/LyShineModule.cpp +++ b/Gems/LyShine/Code/Source/LyShineModule.cpp @@ -52,9 +52,9 @@ #include "World/UiCanvasProxyRefComponent.h" #include "World/UiCanvasOnMeshComponent.h" -#if defined (LYSHINE_EDITOR) -# include "Pipeline/LyShineBuilder/LyShineBuilderComponent.h" -#endif // LYSHINE_EDITOR +#if defined(LYSHINE_BUILDER) +#include "Pipeline/LyShineBuilder/LyShineBuilderComponent.h" +#endif // LYSHINE_BUILDER namespace LyShine { @@ -64,7 +64,7 @@ namespace LyShine // Push results of [MyComponent]::CreateDescriptor() into m_descriptors here. m_descriptors.insert(m_descriptors.end(), { LyShineSystemComponent::CreateDescriptor(), -#if defined (LYSHINE_EDITOR) +#if defined(LYSHINE_EDITOR) LyShineEditor::LyShineEditorSystemComponent::CreateDescriptor(), #endif UiCanvasAssetRefComponent::CreateDescriptor(), @@ -103,7 +103,7 @@ namespace LyShine UiRadioButtonComponent::CreateDescriptor(), UiRadioButtonGroupComponent::CreateDescriptor(), UiParticleEmitterComponent::CreateDescriptor(), - #if defined(LYSHINE_EDITOR) + #if defined(LYSHINE_BUILDER) // Builder LyShineBuilder::LyShineBuilderComponent::CreateDescriptor(), #endif @@ -123,7 +123,7 @@ namespace LyShine { return AZ::ComponentTypeList{ azrtti_typeid(), - #if defined (LYSHINE_EDITOR) + #if defined(LYSHINE_EDITOR) azrtti_typeid(), #endif #if AZ_LOADSCREENCOMPONENT_ENABLED diff --git a/Gems/LyShine/Code/lyshine_common_module_files.cmake b/Gems/LyShine/Code/lyshine_common_module_files.cmake index e725112e53..38d01eb181 100644 --- a/Gems/LyShine/Code/lyshine_common_module_files.cmake +++ b/Gems/LyShine/Code/lyshine_common_module_files.cmake @@ -8,4 +8,6 @@ set(FILES Source/LyShineModule.cpp Source/LyShineModule.h + Source/LyShineSystemComponent.cpp + Source/LyShineSystemComponent.h ) diff --git a/Gems/LyShine/Code/lyshine_static_files.cmake b/Gems/LyShine/Code/lyshine_static_files.cmake index 8c2275ab92..749ce06125 100644 --- a/Gems/LyShine/Code/lyshine_static_files.cmake +++ b/Gems/LyShine/Code/lyshine_static_files.cmake @@ -26,8 +26,6 @@ set(FILES Source/EditorPropertyTypes.h Source/LyShineLoadScreen.cpp Source/LyShineLoadScreen.h - Source/LyShineSystemComponent.cpp - Source/LyShineSystemComponent.h Source/RenderGraph.cpp Source/RenderGraph.h Source/TextMarkup.cpp From a872111ca5718ae4e6948e1cdd5c92ff30670a3e Mon Sep 17 00:00:00 2001 From: michabr <82236305+michabr@users.noreply.github.com> Date: Wed, 14 Jul 2021 15:57:16 -0700 Subject: [PATCH 41/53] Fix LyShine bus attempt to connect twice (#2175) Signed-off-by: abrmich --- Gems/LyShine/Code/Source/LyShineSystemComponent.cpp | 2 -- Gems/LyShine/Code/Source/LyShineSystemComponent.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp b/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp index 7521c8b6c1..b420e551b5 100644 --- a/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp +++ b/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp @@ -148,7 +148,6 @@ namespace LyShine { LyShineAllocatorScope::ActivateAllocators(); - LyShineRequestBus::Handler::BusConnect(); UiSystemBus::Handler::BusConnect(); UiSystemToolsBus::Handler::BusConnect(); UiFrameworkBus::Handler::BusConnect(); @@ -196,7 +195,6 @@ namespace LyShine UiSystemBus::Handler::BusDisconnect(); UiSystemToolsBus::Handler::BusDisconnect(); UiFrameworkBus::Handler::BusDisconnect(); - LyShineRequestBus::Handler::BusDisconnect(); CrySystemEventBus::Handler::BusDisconnect(); LyShineAllocatorScope::DeactivateAllocators(); diff --git a/Gems/LyShine/Code/Source/LyShineSystemComponent.h b/Gems/LyShine/Code/Source/LyShineSystemComponent.h index 5b455715ee..70e7eb5fe5 100644 --- a/Gems/LyShine/Code/Source/LyShineSystemComponent.h +++ b/Gems/LyShine/Code/Source/LyShineSystemComponent.h @@ -13,7 +13,6 @@ #include -#include #include #include #include @@ -28,7 +27,6 @@ namespace LyShine class LyShineSystemComponent : public AZ::Component - , protected LyShineRequestBus::Handler , protected UiSystemBus::Handler , protected UiSystemToolsBus::Handler , protected LyShineAllocatorScope From 67ea31363d9f8f87e7006a0ddcbb70c899e25d3e Mon Sep 17 00:00:00 2001 From: Nicholas Van Sickle Date: Wed, 14 Jul 2021 16:22:08 -0700 Subject: [PATCH 42/53] Fix gesture recognizer spamming errors when clicking the mouse (#2181) The synthetic input devices created by the Qt -> AZ input system were being detected by the gesture recognizer, which confused it - this is a potential general issue for anything listening to the AZ input system out of game mode, but this is the only recorded issue so far. I've added a check in this case to ensure the event comes from the real, physical mouse device instead of one of our synthetic ones, stopping the spam. Signed-off-by: nvsickle --- .../Code/Include/Gestures/IGestureRecognizer.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Gems/Gestures/Code/Include/Gestures/IGestureRecognizer.h b/Gems/Gestures/Code/Include/Gestures/IGestureRecognizer.h index 69e28df102..e606d68a3e 100644 --- a/Gems/Gestures/Code/Include/Gestures/IGestureRecognizer.h +++ b/Gems/Gestures/Code/Include/Gestures/IGestureRecognizer.h @@ -209,12 +209,17 @@ namespace Gestures //////////////////////////////////////////////////////////////////////////////////////////////// inline uint32_t IRecognizer::GetGesturePointerIndex(const AzFramework::InputChannel& inputChannel) { - const auto& mouseButtonIt = AZStd::find(AzFramework::InputDeviceMouse::Button::All.cbegin(), - AzFramework::InputDeviceMouse::Button::All.cend(), - inputChannel.GetInputChannelId()); - if (mouseButtonIt != AzFramework::InputDeviceMouse::Button::All.cend()) + // Only recognize gestures for the default mouse input device. The Editor may register synthetic + // mouse input devices with the same mouse input channels, which can confuse gesture recognition. + if (inputChannel.GetInputDevice().GetInputDeviceId() == AzFramework::InputDeviceMouse::Id) { - return static_cast(mouseButtonIt - AzFramework::InputDeviceMouse::Button::All.cbegin()); + const auto& mouseButtonIt = AZStd::find(AzFramework::InputDeviceMouse::Button::All.cbegin(), + AzFramework::InputDeviceMouse::Button::All.cend(), + inputChannel.GetInputChannelId()); + if (mouseButtonIt != AzFramework::InputDeviceMouse::Button::All.cend()) + { + return static_cast(mouseButtonIt - AzFramework::InputDeviceMouse::Button::All.cbegin()); + } } const auto& touchIndexIt = AZStd::find(AzFramework::InputDeviceTouch::Touch::All.cbegin(), From 72ea2ca1b4509364f9ab0629f8ea904ad6d55d21 Mon Sep 17 00:00:00 2001 From: bosnichd Date: Wed, 14 Jul 2021 17:44:44 -0600 Subject: [PATCH 43/53] Change the InputDeviceImplementationRequest to be addressable by an InputDevcieId to account for the situation where someone may want to swap out the implementation for a single instance of a devcie type rather than all instances of that device type (the latter can still be achieved using Broadcast instead of Event when calling the EBus method). (#2180) Signed-off-by: bosnichd --- .../Buses/Requests/InputDeviceRequestBus.h | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Input/Buses/Requests/InputDeviceRequestBus.h b/Code/Framework/AzFramework/AzFramework/Input/Buses/Requests/InputDeviceRequestBus.h index a1ec4a05f0..a122fe3133 100644 --- a/Code/Framework/AzFramework/AzFramework/Input/Buses/Requests/InputDeviceRequestBus.h +++ b/Code/Framework/AzFramework/AzFramework/Input/Buses/Requests/InputDeviceRequestBus.h @@ -205,6 +205,25 @@ namespace AzFramework class InputDeviceImplementationRequest : public AZ::EBusTraits { public: + //////////////////////////////////////////////////////////////////////////////////////////// + //! EBus Trait: requests can be addressed to a specific InputDeviceId so that they are only + //! handled by one input device that has connected to the bus using that unique id, or they + //! can be broadcast to all input devices that have connected to the bus, regardless of id. + //! Connected input devices are ordered by their local player index from lowest to highest. + static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ByIdAndOrdered; + + //////////////////////////////////////////////////////////////////////////////////////////// + //! EBus Trait: requests should be handled by only one input device connected to each id + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; + + //////////////////////////////////////////////////////////////////////////////////////////// + //! EBus Trait: requests can be addressed to a specific InputDeviceId + using BusIdType = InputDeviceId; + + //////////////////////////////////////////////////////////////////////////////////////////// + //! EBus Trait: requests are handled by connected devices in the order of local player index + using BusIdOrderCompare = AZStd::less; + //////////////////////////////////////////////////////////////////////////////////////////// //! Alias for the EBus implementation of this interface using Bus = AZ::EBus>; @@ -214,11 +233,12 @@ namespace AzFramework using CreateFunctionType = typename InputDeviceType::Implementation*(*)(InputDeviceType&); //////////////////////////////////////////////////////////////////////////////////////////// - //! Create a custom implementation for all the existing instances of this input device type. + //! Set a custom implementation for this input device type, either for a specific instance + //! by addressing the call to an InputDeviceId, or for all existing instances by broadcast. //! Passing InputDeviceType::Implementation::Create as the argument will create the default //! device implementation, while passing nullptr will delete any existing implementation. //! \param[in] createFunction Pointer to the function that will create the implementation. - virtual void CreateCustomImplementation(CreateFunctionType createFunction) = 0; + virtual void SetCustomImplementation(CreateFunctionType createFunction) = 0; }; //////////////////////////////////////////////////////////////////////////////////////////////// @@ -238,7 +258,7 @@ namespace AzFramework AZ_INLINE InputDeviceImplementationRequestHandler(InputDeviceType& inputDevice) : m_inputDevice(inputDevice) { - InputDeviceImplementationRequest::Bus::Handler::BusConnect(); + InputDeviceImplementationRequest::Bus::Handler::BusConnect(m_inputDevice.GetInputDeviceId()); } //////////////////////////////////////////////////////////////////////////////////////////// @@ -251,8 +271,8 @@ namespace AzFramework using CreateFunctionType = typename InputDeviceType::Implementation*(*)(InputDeviceType&); //////////////////////////////////////////////////////////////////////////////////////////// - //! \ref InputDeviceImplementationRequest::CreateCustomImplementation - AZ_INLINE void CreateCustomImplementation(CreateFunctionType createFunction) override + //! \ref InputDeviceImplementationRequest::SetCustomImplementation + AZ_INLINE void SetCustomImplementation(CreateFunctionType createFunction) override { AZStd::unique_ptr newImplementation; if (createFunction) From 4a5ac0e204c683e23caca1405c36e400e9d6d0dc Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Wed, 14 Jul 2021 16:45:36 -0700 Subject: [PATCH 44/53] Fix for ArchiveTest where the assets alias was not being set Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- Code/Framework/AzToolsFramework/Tests/ArchiveTests.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Code/Framework/AzToolsFramework/Tests/ArchiveTests.cpp b/Code/Framework/AzToolsFramework/Tests/ArchiveTests.cpp index 4335e42d62..f706ee824d 100644 --- a/Code/Framework/AzToolsFramework/Tests/ArchiveTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/ArchiveTests.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -111,6 +112,11 @@ namespace UnitTest // shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash // in the unit tests. AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize); + + if (auto fileIoBase = AZ::IO::FileIOBase::GetInstance(); fileIoBase != nullptr) + { + fileIoBase->SetAlias("@assets@", m_tempDir.path().toUtf8().data()); + } } void TearDown() override From 7eeaf7dad5d1c28b0e817cb26bad88df58d0c914 Mon Sep 17 00:00:00 2001 From: SJ Date: Wed, 14 Jul 2021 17:32:07 -0700 Subject: [PATCH 45/53] Generate install layout for Mac (#2144) * 1. Move call to install(TARGETS...) to its own function to create a platform specific implementation for Mac. 2. Add linker-signed flag to work around cmake install issue. Signed-off-by: amzn-sj * Add newline Signed-off-by: amzn-sj * 1. Rename function to ly_install_target_override and only call it if it has been implemented. 2. Pass in runtime, archive, and library directory paths as params to clean it up a bit. Signed-off-by: amzn-sj --- cmake/Platform/Common/Install_common.cmake | 45 ++++++++++++++------ cmake/Platform/Mac/Configurations_mac.cmake | 4 +- cmake/Platform/Mac/Install_mac.cmake | 46 +++++++++++++++++++-- 3 files changed, 78 insertions(+), 17 deletions(-) diff --git a/cmake/Platform/Common/Install_common.cmake b/cmake/Platform/Common/Install_common.cmake index 7ab6006220..20b7a7c81d 100644 --- a/cmake/Platform/Common/Install_common.cmake +++ b/cmake/Platform/Common/Install_common.cmake @@ -100,18 +100,29 @@ function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME absolute_tar cmake_path(RELATIVE_PATH target_library_output_directory BASE_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} OUTPUT_VARIABLE target_library_output_subdirectory) endif() - install( - TARGETS ${TARGET_NAME} - ARCHIVE - DESTINATION ${archive_output_directory}/${PAL_PLATFORM_NAME}/$ - COMPONENT ${install_component} - LIBRARY - DESTINATION ${library_output_directory}/${PAL_PLATFORM_NAME}/$/${target_library_output_subdirectory} - COMPONENT ${install_component} - RUNTIME - DESTINATION ${runtime_output_directory}/${PAL_PLATFORM_NAME}/$/${target_runtime_output_subdirectory} - COMPONENT ${install_component} - ) + if(COMMAND ly_install_target_override) + # Mac needs special handling because of a cmake issue + ly_install_target_override(TARGET ${TARGET_NAME} + ARCHIVE_DIR ${archive_output_directory} + LIBRARY_DIR ${library_output_directory} + RUNTIME_DIR ${runtime_output_directory} + LIBRARY_SUBDIR ${target_library_output_subdirectory} + RUNTIME_SUBDIR ${target_runtime_output_subdirectory} + ) + else() + install( + TARGETS ${TARGET_NAME} + ARCHIVE + DESTINATION ${archive_output_directory}/${PAL_PLATFORM_NAME}/$ + COMPONENT ${install_component} + LIBRARY + DESTINATION ${library_output_directory}/${PAL_PLATFORM_NAME}/$/${target_library_output_subdirectory} + COMPONENT ${install_component} + RUNTIME + DESTINATION ${runtime_output_directory}/${PAL_PLATFORM_NAME}/$/${target_runtime_output_subdirectory} + COMPONENT ${install_component} + ) + endif() # CMakeLists.txt file string(REGEX MATCH "(.*)::(.*)$" match ${ALIAS_TARGET_NAME}) @@ -487,7 +498,7 @@ function(ly_setup_others) # Scripts file(GLOB o3de_scripts "${LY_ROOT_FOLDER}/scripts/o3de.*") - install(FILES + install(PROGRAMS ${o3de_scripts} DESTINATION ./scripts ) @@ -505,6 +516,14 @@ function(ly_setup_others) DESTINATION . REGEX "downloaded_packages" EXCLUDE REGEX "runtime" EXCLUDE + REGEX ".*$\.sh" EXCLUDE + ) + + # For Mac/Linux shell scripts need to be installed as PROGRAMS to have execute permission + file(GLOB python_scripts "${LY_ROOT_FOLDER}/python/*.sh") + install(PROGRAMS + ${python_scripts} + DESTINATION ./python ) # Registry diff --git a/cmake/Platform/Mac/Configurations_mac.cmake b/cmake/Platform/Mac/Configurations_mac.cmake index a3551be3b9..bdb358e9d2 100644 --- a/cmake/Platform/Mac/Configurations_mac.cmake +++ b/cmake/Platform/Mac/Configurations_mac.cmake @@ -28,7 +28,9 @@ else() endif() # Signing -ly_set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS --deep) +# The "-o linker-signed" flag is required as a work-around for the following CMake issue: +# https://gitlab.kitware.com/cmake/cmake/-/issues/21854 +ly_set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "--deep -o linker-signed") # Generate scheme files for Xcode ly_set(CMAKE_XCODE_GENERATE_SCHEME TRUE) diff --git a/cmake/Platform/Mac/Install_mac.cmake b/cmake/Platform/Mac/Install_mac.cmake index 74ebd293ae..40f09a16b0 100644 --- a/cmake/Platform/Mac/Install_mac.cmake +++ b/cmake/Platform/Mac/Install_mac.cmake @@ -5,7 +5,47 @@ # # -# Empty implementations for untested platforms to fix build errors. +#! ly_install_target_override: Mac specific target installation +function(ly_install_target_override) -function(ly_setup_o3de_install) -endfunction() \ No newline at end of file + set(options) + set(oneValueArgs TARGET ARCHIVE_DIR LIBRARY_DIR RUNTIME_DIR LIBRARY_SUBDIR RUNTIME_SUBDIR) + set(multiValueArgs) + cmake_parse_arguments(ly_platform_install_target "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + get_property(install_component TARGET ${ly_platform_install_target_TARGET} PROPERTY INSTALL_COMPONENT) + + # For bundles on Mac, we set the icons by passing in a path to the Images.xcassets directory. + # However, the CMake install command expects paths to files for the the RESOURCE property. + # More details can be found in the CMake issue: https://gitlab.kitware.com/cmake/cmake/-/issues/22409 + get_target_property(is_bundle ${ly_platform_install_target_TARGET} MACOSX_BUNDLE) + if (${is_bundle}) + get_target_property(cached_resources_dir ${ly_platform_install_target_TARGET} RESOURCE) + set_property(TARGET ${ly_platform_install_target_TARGET} PROPERTY RESOURCE "") + endif() + + install( + TARGETS ${ly_platform_install_target_TARGET} + ARCHIVE + DESTINATION ${ly_platform_install_target_ARCHIVE_DIR}/${PAL_PLATFORM_NAME}/$ + COMPONENT ${install_component} + LIBRARY + DESTINATION ${ly_platform_install_target_LIBRARY_DIR}/${PAL_PLATFORM_NAME}/$/${ly_platform_install_target_LIBRARY_SUBDIR} + COMPONENT ${install_component} + RUNTIME + DESTINATION ${ly_platform_install_target_RUNTIME_DIR}/${PAL_PLATFORM_NAME}/$/${ly_platform_install_target_RUNTIME_SUBDIR} + COMPONENT ${install_component} + BUNDLE + DESTINATION ${ly_platform_install_target_RUNTIME_DIR}/${PAL_PLATFORM_NAME}/$/${ly_platform_install_target_RUNTIME_SUBDIR} + COMPONENT ${install_component} + RESOURCE + DESTINATION ${ly_platform_install_target_RUNTIME_DIR}/${PAL_PLATFORM_NAME}/$/${ly_platform_install_target_RUNTIME_SUBDIR}/ + COMPONENT ${install_component} + ) + + if (${is_bundle}) + set_property(TARGET ${ly_platform_install_target_TARGET} PROPERTY RESOURCE ${cached_resources_dir}) + endif() +endfunction() + +include(cmake/Platform/Common/Install_common.cmake) From ae46eea1e82b35f3fc24de49dffdc72e543a7abd Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Wed, 14 Jul 2021 20:24:15 -0700 Subject: [PATCH 46/53] Fix tests in Linux and discover path comparison problem in Windows (fixed) Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- .../AzCore/Tests/AZTestShared/Utils/Utils.cpp | 6 ++-- .../AzFramework/IO/LocalFileIO.cpp | 7 ++--- .../AzToolsFramework/Tests/ArchiveTests.cpp | 29 +++++++------------ .../Tests/AssetFileInfoListComparison.cpp | 17 ++++++++++- .../Tests/AssetSeedManager.cpp | 21 +++++++++++++- .../PlatformAddressedAssetCatalogTests.cpp | 4 +++ 6 files changed, 55 insertions(+), 29 deletions(-) diff --git a/Code/Framework/AzCore/Tests/AZTestShared/Utils/Utils.cpp b/Code/Framework/AzCore/Tests/AZTestShared/Utils/Utils.cpp index a654302da6..d61323f33e 100644 --- a/Code/Framework/AzCore/Tests/AZTestShared/Utils/Utils.cpp +++ b/Code/Framework/AzCore/Tests/AZTestShared/Utils/Utils.cpp @@ -7,9 +7,9 @@ */ #include -#include "AzCore/Component/Entity.h" -#include "AzCore/Asset/AssetManager.h" -#include "AzCore/Slice/SliceComponent.h" +#include +#include +#include namespace UnitTest { diff --git a/Code/Framework/AzFramework/AzFramework/IO/LocalFileIO.cpp b/Code/Framework/AzFramework/AzFramework/IO/LocalFileIO.cpp index 69bf6bb394..96810c20ec 100644 --- a/Code/Framework/AzFramework/AzFramework/IO/LocalFileIO.cpp +++ b/Code/Framework/AzFramework/AzFramework/IO/LocalFileIO.cpp @@ -279,14 +279,11 @@ namespace AZ return SystemFile::Exists(resolvedPath); } - void LocalFileIO::CheckInvalidWrite(const char* path) + void LocalFileIO::CheckInvalidWrite([[maybe_unused]] const char* path) { - (void)path; - #if defined(AZ_ENABLE_TRACING) const char* assetsAlias = GetAlias("@assets@"); - - if (((path) && (assetsAlias) && (azstrnicmp(path, assetsAlias, strlen(assetsAlias)) == 0))) + if (path && assetsAlias && AZ::IO::PathView(path).IsRelativeTo(assetsAlias)) { AZ_Error("FileIO", false, "You may not alter data inside the asset cache. Please check the call stack and consider writing into the source asset folder instead.\n" "Attempted write location: %s", path); diff --git a/Code/Framework/AzToolsFramework/Tests/ArchiveTests.cpp b/Code/Framework/AzToolsFramework/Tests/ArchiveTests.cpp index f706ee824d..3b08e04304 100644 --- a/Code/Framework/AzToolsFramework/Tests/ArchiveTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/ArchiveTests.cpp @@ -24,6 +24,7 @@ #include #include #include +#include namespace UnitTest { @@ -73,7 +74,7 @@ namespace UnitTest void CreateArchiveFolder( QString archiveFolderName, QStringList fileList ) { - QDir tempPath = QDir(m_tempDir.path()).filePath(archiveFolderName); + QDir tempPath = QDir(m_tempDir.GetDirectory()).filePath(archiveFolderName); for (const auto& thisFile : fileList) { @@ -89,12 +90,12 @@ namespace UnitTest QString GetArchivePath() { - return QDir(m_tempDir.path()).filePath("TestArchive.pak"); + return QDir(m_tempDir.GetDirectory()).filePath("TestArchive.pak"); } QString GetArchiveFolder() { - return QDir(m_tempDir.path()).filePath(GetArchiveFolderName()); + return QDir(m_tempDir.GetDirectory()).filePath(GetArchiveFolderName()); } bool CreateArchive() @@ -115,7 +116,7 @@ namespace UnitTest if (auto fileIoBase = AZ::IO::FileIOBase::GetInstance(); fileIoBase != nullptr) { - fileIoBase->SetAlias("@assets@", m_tempDir.path().toUtf8().data()); + fileIoBase->SetAlias("@assets@", m_tempDir.GetDirectory()); } } @@ -126,16 +127,12 @@ namespace UnitTest } AZStd::unique_ptr m_app; - QTemporaryDir m_tempDir {QDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation)).filePath("ArchiveTests-")}; + UnitTest::ScopedTemporaryDirectory m_tempDir; }; -#if AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS - TEST_F(ArchiveTest, DISABLED_CreateArchiveBlocking_FilesAtThreeDepths_ArchiveCreated) -#else TEST_F(ArchiveTest, CreateArchiveBlocking_FilesAtThreeDepths_ArchiveCreated) -#endif // AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS { - EXPECT_TRUE(m_tempDir.isValid()); + EXPECT_TRUE(m_tempDir.IsValid()); CreateArchiveFolder(); bool createResult = CreateArchive(); @@ -143,13 +140,9 @@ namespace UnitTest EXPECT_EQ(createResult, true); } -#if AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS - TEST_F(ArchiveTest, DISABLED_ListFilesInArchiveBlocking_FilesAtThreeDepths_FilesFound) -#else TEST_F(ArchiveTest, ListFilesInArchiveBlocking_FilesAtThreeDepths_FilesFound) -#endif // AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS { - EXPECT_TRUE(m_tempDir.isValid()); + EXPECT_TRUE(m_tempDir.IsValid()); CreateArchiveFolder(); EXPECT_EQ(CreateArchive(), true); @@ -161,11 +154,7 @@ namespace UnitTest EXPECT_EQ(fileList.size(), 6); } -#if AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS - TEST_F(ArchiveTest, DISABLED_CreateDeltaCatalog_AssetsNotRegistered_Failure) -#else TEST_F(ArchiveTest, CreateDeltaCatalog_AssetsNotRegistered_Failure) -#endif // AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS { QStringList fileList = CreateArchiveFileList(); @@ -209,7 +198,9 @@ namespace UnitTest } bool catalogCreated{ false }; + AZ_TEST_START_TRACE_SUPPRESSION; AzToolsFramework::AssetBundleCommandsBus::BroadcastResult(catalogCreated, &AzToolsFramework::AssetBundleCommandsBus::Events::CreateDeltaCatalog, GetArchivePath().toStdString().c_str(), true); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // produces different counts in different platforms EXPECT_EQ(catalogCreated, true); } } diff --git a/Code/Framework/AzToolsFramework/Tests/AssetFileInfoListComparison.cpp b/Code/Framework/AzToolsFramework/Tests/AssetFileInfoListComparison.cpp index 2e4641d818..fea9fa6cc1 100644 --- a/Code/Framework/AzToolsFramework/Tests/AssetFileInfoListComparison.cpp +++ b/Code/Framework/AzToolsFramework/Tests/AssetFileInfoListComparison.cpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace // anonymous { @@ -57,7 +58,8 @@ namespace UnitTest AZ::IO::FileIOBase::SetInstance(nullptr); AZ::IO::FileIOBase::SetInstance(m_localFileIO); - AZ::IO::FileIOBase::GetInstance()->SetAlias("@assets@", GetTestFolderPath().c_str()); + AZ::IO::FileIOBase::GetInstance()->SetAlias("@assets@", m_tempDir.GetDirectory()); + AZStd::string assetRoot = AzToolsFramework::PlatformAddressedAssetCatalog::GetAssetRootForPlatform(AzFramework::PlatformId::PC); for (int idx = 0; idx < TotalAssets; idx++) @@ -69,9 +71,11 @@ namespace UnitTest assetRegistry.RegisterAsset(m_assets[idx], info); AzFramework::StringFunc::Path::Join(assetRoot.c_str(), info.m_relativePath.c_str(), m_assetsPath[idx]); + AZ_TEST_START_TRACE_SUPPRESSION; if (m_fileStreams[idx].Open(m_assetsPath[idx].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { m_fileStreams[idx].Write(info.m_relativePath.size(), info.m_relativePath.data()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder } else { @@ -115,10 +119,12 @@ namespace UnitTest // Modify contents of asset2 int fileIndex = 2; + AZ_TEST_START_TRACE_SUPPRESSION; if (m_fileStreams[fileIndex].Open(m_assetsPath[fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { AZStd::string fileContent = AZStd::string::format("new Asset%d.txt", fileIndex);// changing file content m_fileStreams[fileIndex].Write(fileContent.size(), fileContent.c_str()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder } else { @@ -127,10 +133,12 @@ namespace UnitTest // Modify contents of asset 4 fileIndex = 4; + AZ_TEST_START_TRACE_SUPPRESSION; if (m_fileStreams[fileIndex].Open(m_assetsPath[fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { AZStd::string fileContent = AZStd::string::format("new Asset%d.txt", fileIndex);// changing file content m_fileStreams[fileIndex].Write(fileContent.size(), fileContent.c_str()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder } else { @@ -152,7 +160,9 @@ namespace UnitTest { if (fileIO->Exists(TempFiles[idx])) { + AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(TempFiles[idx]); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder } } @@ -163,14 +173,18 @@ namespace UnitTest m_fileStreams[idx].Close(); if (fileIO->Exists(m_assetsPath[idx].c_str())) { + AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(m_assetsPath[idx].c_str()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder } } auto pcCatalogFile = AzToolsFramework::PlatformAddressedAssetCatalog::GetCatalogRegistryPathForPlatform(AzFramework::PlatformId::PC); if (fileIO->Exists(pcCatalogFile.c_str())) { + AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(pcCatalogFile.c_str()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder } delete m_pcCatalog; @@ -728,6 +742,7 @@ namespace UnitTest } ToolsTestApplication* m_application; + UnitTest::ScopedTemporaryDirectory m_tempDir; AzToolsFramework::PlatformAddressedAssetCatalog* m_pcCatalog; AZ::IO::FileIOBase* m_priorFileIO = nullptr; AZ::IO::FileIOBase* m_localFileIO = nullptr; diff --git a/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp b/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp index 52b8cc6a52..9ac53e4702 100644 --- a/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp +++ b/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp @@ -87,10 +87,12 @@ namespace UnitTest for (int idx = 0; idx < s_totalAssets; idx++) { AzFramework::StringFunc::Path::Join(assetRoot.c_str(), m_assetsPath[idx].c_str(), m_assetsPathFull[platformCount][idx]); + AZ_TEST_START_TRACE_SUPPRESSION; if (m_fileStreams[platformCount][idx].Open(m_assetsPathFull[platformCount][idx].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { m_fileStreams[platformCount][idx].Write(m_assetsPath[idx].size(), m_assetsPath[idx].data()); m_fileStreams[platformCount][idx].Close(); + AZ_TEST_STOP_TRACE_SUPPRESSION(thisPlatform == AzFramework::PlatformId::PC ? 1 : 0); // writing to asset cache folder, only invalid for PC } else { @@ -112,7 +114,9 @@ namespace UnitTest m_testDynamicSliceAssetId = testDynamicSliceAsset; m_assetRegistry->RegisterAsset(testDynamicSliceAsset, dynamicSliceAssetInfo); + AZ_TEST_START_TRACE_SUPPRESSION; AZ::IO::FileIOStream dynamicSliceFileIOStream(TestDynamicSliceAssetPath, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder AZ::Data::AssetInfo sliceAssetInfo; sliceAssetInfo.m_relativePath = TestSliceAssetPath; @@ -124,7 +128,9 @@ namespace UnitTest secondSliceAssetInfo.m_assetId = secondTestSliceAsset; m_assetRegistry->RegisterAsset(secondTestSliceAsset, secondSliceAssetInfo); + AZ_TEST_START_TRACE_SUPPRESSION; AZ::IO::FileIOStream sliceFileIOStream(TestSliceAssetPath, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder // asset0 -> asset1 -> asset2 -> asset4 // --> asset3 @@ -186,7 +192,6 @@ namespace UnitTest AZ::IO::Path assetRoot(AZ::Utils::GetProjectPath()); assetRoot /= "Cache"; AZ::IO::FileIOBase::GetInstance()->SetAlias("@root@", assetRoot.c_str()); - } void TearDown() override @@ -195,7 +200,9 @@ namespace UnitTest if (fileIO->Exists(s_catalogFile)) { + AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(s_catalogFile); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder } for (size_t platformCount = 0; platformCount < s_totalTestPlatforms; ++platformCount) @@ -206,26 +213,34 @@ namespace UnitTest // we need to close the handle before we try to remove the file if (fileIO->Exists(m_assetsPathFull[platformCount][idx].c_str())) { + AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(m_assetsPathFull[platformCount][idx].c_str()); + AZ_TEST_STOP_TRACE_SUPPRESSION(platformCount == 0 ? 1 : 0); // deleting from asset cache folder } } } if (fileIO->Exists(TestSliceAssetPath)) { + AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(TestSliceAssetPath); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder } if (fileIO->Exists(TestDynamicSliceAssetPath)) { + AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(TestDynamicSliceAssetPath); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder } auto pcCatalogFile = AzToolsFramework::PlatformAddressedAssetCatalog::GetCatalogRegistryPathForPlatform(AzFramework::PlatformId::PC); auto androidCatalogFile = AzToolsFramework::PlatformAddressedAssetCatalog::GetCatalogRegistryPathForPlatform(AzFramework::PlatformId::ANDROID_ID); if (fileIO->Exists(pcCatalogFile.c_str())) { + AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(pcCatalogFile.c_str()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder } if (fileIO->Exists(androidCatalogFile.c_str())) @@ -629,11 +644,13 @@ namespace UnitTest EXPECT_EQ(assetList1.m_fileInfoList.size(), 1); EXPECT_TRUE(Search(assetList1, assets[fileIndex])); + AZ_TEST_START_TRACE_SUPPRESSION; if (m_fileStreams[0][fileIndex].Open(m_assetsPathFull[0][fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { AZStd::string fileContent = AZStd::string::format("asset%d.txt", fileIndex); m_fileStreams[0][fileIndex].Write(fileContent.size(), fileContent.c_str()); m_fileStreams[0][fileIndex].Close(); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder } AzToolsFramework::AssetFileInfoList assetList2 = m_assetSeedManager->GetDependencyList(AzFramework::PlatformId::PC); @@ -660,11 +677,13 @@ namespace UnitTest EXPECT_EQ(assetList1.m_fileInfoList.size(), 1); EXPECT_TRUE(Search(assetList1, assets[fileIndex])); + AZ_TEST_START_TRACE_SUPPRESSION; if (m_fileStreams[0][fileIndex].Open(m_assetsPathFull[0][fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { AZStd::string fileContent = AZStd::string::format("asset%d.txt", fileIndex + 1);// changing file content m_fileStreams[0][fileIndex].Write(fileContent.size(), fileContent.c_str()); m_fileStreams[0][fileIndex].Close(); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder } AzToolsFramework::AssetFileInfoList assetList2 = m_assetSeedManager->GetDependencyList(AzFramework::PlatformId::PC); diff --git a/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp b/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp index 29b48a1f31..3446f854b6 100644 --- a/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp @@ -83,9 +83,11 @@ namespace UnitTest info.m_assetId = m_assets[platformNum][idx]; assetRegistry->RegisterAsset(m_assets[platformNum][idx], info); m_assetsPath[platformNum][idx] = info.m_relativePath; + AZ_TEST_START_TRACE_SUPPRESSION; if (m_fileStreams[platformNum][idx].Open(m_assetsPath[platformNum][idx].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { m_fileStreams[platformNum][idx].Write(info.m_relativePath.size(), info.m_relativePath.data()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder } else { @@ -131,7 +133,9 @@ namespace UnitTest m_fileStreams[platformNum][idx].Close(); if (fileIO->Exists(m_assetsPath[platformNum][idx].c_str())) { + AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(m_assetsPath[platformNum][idx].c_str()); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // removing from asset cache folder } } } From 104e0f73bf66345df328771d94c351353e1066ff Mon Sep 17 00:00:00 2001 From: lsemp3d <58790905+lsemp3d@users.noreply.github.com> Date: Wed, 14 Jul 2021 18:31:50 -0700 Subject: [PATCH 47/53] Fixed Lua class enumeration, there was a crash when traversing into methods Signed-off-by: lsemp3d <58790905+lsemp3d@users.noreply.github.com> --- .../AzCore/Script/ScriptContextDebug.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Script/ScriptContextDebug.cpp b/Code/Framework/AzCore/AzCore/Script/ScriptContextDebug.cpp index b68b19ddda..0444c4ce2a 100644 --- a/Code/Framework/AzCore/AzCore/Script/ScriptContextDebug.cpp +++ b/Code/Framework/AzCore/AzCore/Script/ScriptContextDebug.cpp @@ -157,8 +157,11 @@ ScriptContextDebug::EnumRegisteredClasses(EnumClass enumClass, EnumMethod enumMe lua_pop(l, 2); // pop the Class name and behaviorClass lua_pushnil(l); + + // iterate over the key/value pairs while (lua_next(l, -2) != 0) { + // if key: string value: function if (lua_isstring(l, -2) && lua_isfunction(l, -1)) { const char* name = lua_tostring(l, -2); @@ -167,6 +170,7 @@ ScriptContextDebug::EnumRegisteredClasses(EnumClass enumClass, EnumMethod enumMe bool isRead = true; bool isWrite = true; + // check if there is a getter provided lua_getupvalue(l, -1, 1); if (lua_isnil(l, -1)) { @@ -174,6 +178,7 @@ ScriptContextDebug::EnumRegisteredClasses(EnumClass enumClass, EnumMethod enumMe } lua_pop(l, 1); + // check if there is a setter provided lua_getupvalue(l, -1, 2); if (lua_isnil(l, -1)) { @@ -181,6 +186,7 @@ ScriptContextDebug::EnumRegisteredClasses(EnumClass enumClass, EnumMethod enumMe } lua_pop(l, 1); + // enumerate the remaining property if (!enumProperty(&behaviorClass->m_typeId, name, isRead, isWrite, userData)) { lua_pop(l, 5); @@ -189,21 +195,30 @@ ScriptContextDebug::EnumRegisteredClasses(EnumClass enumClass, EnumMethod enumMe } else { + // for any non-built in methods if (strncmp(name, "__", 2) != 0) { const char* dbgParamInfo = NULL; - lua_getupvalue(l, -1, 2); + + // attempt to get the name + bool popDebugName = lua_getupvalue(l, -1, 2) != nullptr; if (lua_isstring(l, -1)) { dbgParamInfo = lua_tostring(l, -1); } + // enumerate the method's parameters if (!enumMethod(&behaviorClass->m_typeId, name, dbgParamInfo, userData)) { lua_pop(l, 6); return; } - lua_pop(l, 1); // pop the DBG name + + // if we were able to get the name, pop it from the stack + if (popDebugName) + { + lua_pop(l, 1); + } } } } From a077a88d3f7b066fd26446b7e6e821f66dcc9b9a Mon Sep 17 00:00:00 2001 From: Chris Burel Date: Wed, 14 Jul 2021 23:44:40 -0700 Subject: [PATCH 48/53] [MeshOptimizer] Determine the original vertex index based on the position (#2008) * Determine the original vertex index based on the position The Assimp library does not expose the FBX control point indices. This change causes vertices that are close enough in their position to be considered as coming from the same control point. This allows the mesh optimizer to consider vertices with the same control point index (or "original vertex index" as it is called in the code) for deduplication. Signed-off-by: Chris Burel * Use a filter view instead of reimplementing a filter view Signed-off-by: Chris Burel * Don't attempt to weld similar vertices if there's blendshapes Signed-off-by: Chris Burel * Add test for the mesh optimizer's ability to weld nearby vertices Signed-off-by: Chris Burel * Add logging call to show mesh optimizer effect on vertex count Signed-off-by: Chris Burel * Use a bunch of temporaries in order to make `position` `const` Signed-off-by: Chris Burel * Supply the vertex index remapping to the optimized skin weights This ensures that the optimized skin weights use the vertex indexes from the optimized mesh Signed-off-by: Chris Burel --- .../SceneAPI/SceneData/Groups/MeshGroup.h | 24 +- Gems/SceneProcessing/Code/CMakeLists.txt | 1 + .../MeshOptimizer/MeshOptimizerComponent.cpp | 127 ++++++++-- .../MeshOptimizerComponentTests.cpp | 221 ++++++++++++++++++ .../sceneprocessing_editor_tests_files.cmake | 1 + 5 files changed, 340 insertions(+), 34 deletions(-) create mode 100644 Gems/SceneProcessing/Code/Tests/MeshBuilder/MeshOptimizerComponentTests.cpp diff --git a/Code/Tools/SceneAPI/SceneData/Groups/MeshGroup.h b/Code/Tools/SceneAPI/SceneData/Groups/MeshGroup.h index c06c91a808..5b4c4612ad 100644 --- a/Code/Tools/SceneAPI/SceneData/Groups/MeshGroup.h +++ b/Code/Tools/SceneAPI/SceneData/Groups/MeshGroup.h @@ -28,27 +28,27 @@ namespace AZ } namespace SceneData { - class MeshGroup + class SCENE_DATA_CLASS MeshGroup : public DataTypes::IMeshGroup { public: AZ_RTTI(MeshGroup, "{07B356B7-3635-40B5-878A-FAC4EFD5AD86}", DataTypes::IMeshGroup); AZ_CLASS_ALLOCATOR(MeshGroup, SystemAllocator, 0) - MeshGroup(); - ~MeshGroup() override = default; + SCENE_DATA_API MeshGroup(); + SCENE_DATA_API ~MeshGroup() override = default; - const AZStd::string& GetName() const override; - void SetName(const AZStd::string& name); - void SetName(AZStd::string&& name) override; - const Uuid& GetId() const override; - void OverrideId(const Uuid& id) override; + SCENE_DATA_API const AZStd::string& GetName() const override; + SCENE_DATA_API void SetName(const AZStd::string& name); + SCENE_DATA_API void SetName(AZStd::string&& name) override; + SCENE_DATA_API const Uuid& GetId() const override; + SCENE_DATA_API void OverrideId(const Uuid& id) override; - Containers::RuleContainer& GetRuleContainer() override; - const Containers::RuleContainer& GetRuleContainerConst() const override; + SCENE_DATA_API Containers::RuleContainer& GetRuleContainer() override; + SCENE_DATA_API const Containers::RuleContainer& GetRuleContainerConst() const override; - DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList() override; - const DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList() const override; + SCENE_DATA_API DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList() override; + SCENE_DATA_API const DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList() const override; static void Reflect(AZ::ReflectContext* context); static bool VersionConverter(SerializeContext& context, SerializeContext::DataElementNode& classElement); diff --git a/Gems/SceneProcessing/Code/CMakeLists.txt b/Gems/SceneProcessing/Code/CMakeLists.txt index b33e157e51..57fc458d70 100644 --- a/Gems/SceneProcessing/Code/CMakeLists.txt +++ b/Gems/SceneProcessing/Code/CMakeLists.txt @@ -112,6 +112,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) PRIVATE Gem::SceneProcessing.Editor.Static AZ::AzTest + AZ::SceneData ) ly_add_googletest( NAME Gem::SceneProcessing.Editor.Tests diff --git a/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp b/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp index e3eb617601..634dafa99c 100644 --- a/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp +++ b/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp @@ -96,6 +96,85 @@ namespace AZ::SceneGenerationComponents namespace Containers = AZ::SceneAPI::Containers; namespace Views = Containers::Views; + // @brief A class to map from a mesh's vertex index to it's welded vertex index + // + // When the mesh optimizer runs, it welds nearby vertices (if there are no blendshapes). This class provides a + // constant time lookup to map from an unwelded vertex index to the welded one. + // The welding works by rounding the vertex's position to the given position tolerance, then uses that rounded + // Vector3 as a key into a unordered_map. + template + class Vector3Map + : private AZStd::unordered_map + { + public: + Vector3Map(const MeshDataType* meshData, bool hasBlendShapes, float positionTolerance) + : m_meshData(meshData) + , m_hasBlendShapes(hasBlendShapes) + , m_positionTolerance(positionTolerance) + , m_positionToleranceReciprocal(1.0f / positionTolerance) + { + } + + using AZStd::unordered_map::reserve; + + AZ::u32 operator[](const AZ::u32 vertexIndex) + { + if (m_hasBlendShapes) + { + // Don't attempt to weld similar vertices if there's blendshapes + // Welding the vertices here based on position could cause the vertices of a base shape to be welded, + // and the vertices of the blendshape to not be welded, resulting in a vertex count mismatch between + // the two + return m_meshData->GetUsedPointIndexForControlPoint(m_meshData->GetControlPointIndex(vertexIndex)); + } + + const auto& [iter, didInsert] = try_emplace(GetPositionForIndex(vertexIndex), m_currentOriginalVertexIndex); + if (didInsert) + { + ++m_currentOriginalVertexIndex; + } + return iter->second; + } + + [[nodiscard]] AZ::u32 at(const AZ::u32 vertexIndex) const + { + if (m_hasBlendShapes) + { + // Don't attempt to weld similar vertices if there's blendshapes + // Welding the vertices here based on position could cause the vertices of a base shape to be welded, + // and the vertices of the blendshape to not be welded, resulting in a vertex count mismatch between + // the two + return m_meshData->GetUsedPointIndexForControlPoint(m_meshData->GetControlPointIndex(vertexIndex)); + } + + auto iter = find(GetPositionForIndex(vertexIndex)); + AZSTD_CONTAINER_ASSERT(iter != end(), "Element with key is not present"); + return iter->second; + } + + private: + + AZ::Vector3 GetPositionForIndex(const AZ::u32 vertexIndex) const + { + // Round the vertex position so that a float comparison can be made with entires in the map + // pos = floor( x * 10 + 0.5) * 0.1 + return AZ::Vector3( + AZ::Simd::Vec3::Floor( + (m_meshData->GetPosition(vertexIndex) * m_positionToleranceReciprocal + AZ::Vector3(0.5f)).GetSimdValue() + ) + ) * m_positionTolerance; + } + + const MeshDataType* m_meshData; + bool m_hasBlendShapes; + float m_positionTolerance; + float m_positionToleranceReciprocal; + AZ::u32 m_currentOriginalVertexIndex = 0; + }; + + template + Vector3Map(const MeshDataType*) -> Vector3Map; + MeshOptimizerComponent::MeshOptimizerComponent() { BindToCall(&MeshOptimizerComponent::OptimizeMeshes); @@ -106,7 +185,7 @@ namespace AZ::SceneGenerationComponents auto* serializeContext = azrtti_cast(context); if (serializeContext) { - serializeContext->Class()->Version(2); + serializeContext->Class()->Version(4); } } @@ -115,7 +194,8 @@ namespace AZ::SceneGenerationComponents const MeshDataType* meshData, const SkinWeightDataView& skinWeights, AZ::u32 maxWeightsPerVertex, - float weightThreshold) + float weightThreshold, + const Vector3Map& positionMap) { if (skinWeights.empty()) { @@ -141,15 +221,12 @@ namespace AZ::SceneGenerationComponents for (size_t linkIndex = 0; linkIndex < linkCount; ++linkIndex) { const ISkinWeightData::Link& link = skinData.get().GetLink(controlPointIndex, linkIndex); - skinningInfo->AddInfluence(usedPointIndex, {aznumeric_caster(link.boneId), link.weight}); + skinningInfo->AddInfluence(positionMap.at(usedPointIndex), {aznumeric_caster(link.boneId), link.weight}); } } } - if (skinningInfo) - { - skinningInfo->Optimize(maxWeightsPerVertex, weightThreshold); - } + skinningInfo->Optimize(maxWeightsPerVertex, weightThreshold); return skinningInfo; } @@ -192,17 +269,12 @@ namespace AZ::SceneGenerationComponents const AZStd::vector> meshes = [](const SceneGraph& graph) { AZStd::vector> meshes; - for (auto it = graph.GetContentStorage().cbegin(); it != graph.GetContentStorage().cend(); ++it) + const auto meshNodes = Containers::MakeDerivedFilterView(graph.GetContentStorage()); + for (auto it = meshNodes.cbegin(); it != meshNodes.cend(); ++it) { - // Skip anything that isn't a mesh. - const auto* mesh = azdynamic_cast(it->get()); - if (!mesh) - { - continue; - } - // Get the mesh data and node index and store them in the vector as a pair, so we can iterate over them later. - meshes.emplace_back(mesh, graph.ConvertToNodeIndex(it)); + // The sequential calls to GetBaseIterator unwrap the layers of FilterIterators from the MakeDerivedFilterView + meshes.emplace_back(&(*it), graph.ConvertToNodeIndex(it.GetBaseIterator().GetBaseIterator().GetBaseIterator())); } return meshes; }(graph); @@ -287,6 +359,12 @@ namespace AZ::SceneGenerationComponents auto [optimizedMesh, optimizedUVs, optimizedTangents, optimizedBitangents, optimizedVertexColors, optimizedSkinWeights] = OptimizeMesh(mesh, mesh, uvDatas, tangentDatas, bitangentDatas, colorDatas, skinWeightDatas, meshGroup, hasBlendShapes); + AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Base mesh: %zu vertices, optimized mesh: %zu vertices, %0.02f%% of the original", + mesh->GetUsedControlPointCount(), + optimizedMesh->GetUsedControlPointCount(), + ((float)optimizedMesh->GetUsedControlPointCount() / (float)mesh->GetUsedControlPointCount()) * 100.0f + ); + const NodeIndex optimizedMeshNodeIndex = graph.AddChild(graph.GetNodeParent(nodeIndex), name.c_str(), AZStd::move(optimizedMesh)); auto addOptimizedNodes = [&graph, &optimizedMeshNodeIndex](const auto& originalNodeIndexes, auto& optimizedNodes) @@ -428,10 +506,9 @@ namespace AZ::SceneGenerationComponents const AZStd::vector bitangentLayers = makeLayersForData(bitangents); const AZStd::vector vertexColorLayers = makeLayersForData(vertexColors); - const auto* skinRule = meshGroup.GetRuleContainerConst().FindFirstByType().get(); - const AZ::u32 maxWeightsPerVertex = skinRule ? skinRule->GetMaxWeightsPerVertex() : 4; - const float weightThreshold = skinRule ? skinRule->GetWeightThreshold() : 0.001f; - meshBuilder.SetSkinningInfo(ExtractSkinningInfo(meshData, skinWeights, maxWeightsPerVertex, weightThreshold)); + constexpr float positionTolerance = 0.0001f; + Vector3Map positionMap(meshData, hasBlendShapes, positionTolerance); + positionMap.reserve(vertexCount); // Add the vertex data to all the layers const AZ::u32 faceCount = meshData->GetFaceCount(); @@ -440,8 +517,8 @@ namespace AZ::SceneGenerationComponents meshBuilder.BeginPolygon(baseMesh->GetFaceMaterialId(faceIndex)); for (const AZ::u32 vertexIndex : meshData->GetFaceInfo(faceIndex).vertexIndex) { - const int orgVertexNumber = meshData->GetUsedPointIndexForControlPoint(meshData->GetControlPointIndex(vertexIndex)); - AZ_Assert(orgVertexNumber >= 0, "Invalid vertex number"); + const AZ::u32 orgVertexNumber = positionMap[vertexIndex]; + orgVtxLayer->SetCurrentVertexValue(orgVertexNumber); posLayer->SetCurrentVertexValue(meshData->GetPosition(vertexIndex)); @@ -471,6 +548,12 @@ namespace AZ::SceneGenerationComponents meshBuilder.EndPolygon(); } + + const auto* skinRule = meshGroup.GetRuleContainerConst().FindFirstByType().get(); + const AZ::u32 maxWeightsPerVertex = skinRule ? skinRule->GetMaxWeightsPerVertex() : 4; + const float weightThreshold = skinRule ? skinRule->GetWeightThreshold() : 0.001f; + meshBuilder.SetSkinningInfo(ExtractSkinningInfo(meshData, skinWeights, maxWeightsPerVertex, weightThreshold, positionMap)); + meshBuilder.GenerateSubMeshVertexOrders(); // Create the resulting nodes diff --git a/Gems/SceneProcessing/Code/Tests/MeshBuilder/MeshOptimizerComponentTests.cpp b/Gems/SceneProcessing/Code/Tests/MeshBuilder/MeshOptimizerComponentTests.cpp new file mode 100644 index 0000000000..81528fc3e4 --- /dev/null +++ b/Gems/SceneProcessing/Code/Tests/MeshBuilder/MeshOptimizerComponentTests.cpp @@ -0,0 +1,221 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace AZ::SceneAPI::DataTypes +{ + void PrintTo(const ISkinWeightData::Link& link, ::std::ostream* os) + { + *os << '{' << link.boneId << ", " << link.weight << '}'; + } +} + +namespace SceneProcessing +{ + class VertexDeduplicationFixture + : public SceneProcessing::InitSceneAPIFixture + { + public: + void SetUp() override + { + SceneProcessing::InitSceneAPIFixture::SetUp(); + + m_systemEntity = m_app.Create({}, {}); + m_systemEntity->AddComponent(aznew AZ::MemoryComponent()); + m_systemEntity->AddComponent(aznew AZ::JobManagerComponent()); + m_systemEntity->Init(); + m_systemEntity->Activate(); + } + void TearDown() override + { + m_systemEntity->Deactivate(); + SceneProcessing::InitSceneAPIFixture::TearDown(); + } + + static AZStd::unique_ptr MakePlaneMesh() + { + // Create a simple plane with 2 triangles, 6 total vertices, 2 shared vertices + // 0 --- 1 + // | / | + // | / | + // | / | + // 2 --- 3 + const AZStd::array planeVertexPositions = { + AZ::Vector3{0.0f, 0.0f, 0.0f}, + AZ::Vector3{0.0f, 0.0f, 1.0f}, + AZ::Vector3{1.0f, 0.0f, 1.0f}, + AZ::Vector3{1.0f, 0.0f, 1.0f}, + AZ::Vector3{1.0f, 0.0f, 0.0f}, + AZ::Vector3{0.0f, 0.0f, 0.0f}, + }; + + auto mesh = AZStd::make_unique(); + + int i = 0; + for (const AZ::Vector3& position : planeVertexPositions) + { + mesh->AddPosition(position); + mesh->AddNormal(AZ::Vector3::CreateAxisY()); + + // This assumes that the data coming from the import process gives a unique control point + // index to every vertex. This follows the behavior of the AssImp library. + mesh->SetVertexIndexToControlPointIndexMap(i, i); + ++i; + } + + mesh->AddFace({0, 1, 2}, 0); + mesh->AddFace({3, 4, 5}, 0); + + return mesh; + } + + static AZStd::unique_ptr MakeSkinData() + { + auto skinWeights = AZStd::make_unique(); + + skinWeights->ResizeContainerSpace(6); + + // Add bones 0 and 1 to the skin weights + skinWeights->GetBoneId("0"); + skinWeights->GetBoneId("1"); + + skinWeights->AppendLink(0, {/*.boneId=*/0, /*.weight=*/1}); + skinWeights->AppendLink(1, {/*.boneId=*/0, /*.weight=*/1}); + skinWeights->AppendLink(2, {/*.boneId=*/0, /*.weight=*/1}); + skinWeights->AppendLink(3, {/*.boneId=*/1, /*.weight=*/1}); + skinWeights->AppendLink(4, {/*.boneId=*/1, /*.weight=*/1}); + skinWeights->AppendLink(5, {/*.boneId=*/1, /*.weight=*/1}); + + return skinWeights; + } + + private: + AZ::ComponentApplication m_app; + AZ::Entity* m_systemEntity; + }; + + TEST_F(VertexDeduplicationFixture, CanDeduplicateVertices) + { + AZ::SceneAPI::Containers::Scene scene("testScene"); + AZ::SceneAPI::Containers::SceneGraph& graph = scene.GetGraph(); + + const auto meshNodeIndex = graph.AddChild(graph.GetRoot(), "testMesh", MakePlaneMesh()); + + // The original source mesh should have 6 vertices + EXPECT_EQ(AZStd::rtti_pointer_cast(graph.GetNodeContent(meshNodeIndex))->GetVertexCount(), 6); + + auto meshGroup = AZStd::make_unique(); + meshGroup->GetSceneNodeSelectionList().AddSelectedNode("testMesh"); + scene.GetManifest().AddEntry(AZStd::move(meshGroup)); + + AZ::SceneGenerationComponents::MeshOptimizerComponent component; + AZ::SceneAPI::Events::GenerateSimplificationEventContext context(scene, "pc"); + component.OptimizeMeshes(context); + + AZ::SceneAPI::Containers::SceneGraph::NodeIndex optimizedNodeIndex = graph.Find(AZStd::string("testMesh").append(AZ::SceneAPI::Utilities::OptimizedMeshSuffix)); + ASSERT_TRUE(optimizedNodeIndex.IsValid()) << "Mesh optimizer did not add an optimized version of the mesh"; + + const auto& optimizedMesh = AZStd::rtti_pointer_cast(graph.GetNodeContent(optimizedNodeIndex)); + ASSERT_TRUE(optimizedMesh); + + // The optimized mesh should have 4 vertices, the 2 shared vertices are welded together + EXPECT_EQ(optimizedMesh->GetVertexCount(), 4); + } + + MATCHER(VectorOfLinksEq, "") + { + return testing::ExplainMatchResult( + testing::AllOf( + testing::Field(&AZ::SceneData::GraphData::SkinWeightData::Link::boneId, testing::Eq(testing::get<0>(arg).boneId)), + testing::Field(&AZ::SceneData::GraphData::SkinWeightData::Link::weight, testing::FloatEq(testing::get<0>(arg).weight)) + ), + testing::get<1>(arg), + result_listener + ); + } + + MATCHER(VectorOfVectorOfLinksEq, "") + { + return testing::ExplainMatchResult( + testing::UnorderedPointwise(VectorOfLinksEq(), testing::get<0>(arg)), + testing::get<1>(arg), + result_listener + ); + } + + TEST_F(VertexDeduplicationFixture, DeduplicatedVerticesRemapSkinning) + { + AZ::SceneAPI::Containers::Scene scene("testScene"); + AZ::SceneAPI::Containers::SceneGraph& graph = scene.GetGraph(); + + const auto meshNodeIndex = graph.AddChild(graph.GetRoot(), "testMesh", MakePlaneMesh()); + const auto skinDataNodeIndex = graph.AddChild(meshNodeIndex, "skinData", MakeSkinData()); + graph.MakeEndPoint(skinDataNodeIndex); + + // The original source mesh should have 6 vertices + EXPECT_EQ(AZStd::rtti_pointer_cast(graph.GetNodeContent(meshNodeIndex))->GetVertexCount(), 6); + + auto meshGroup = AZStd::make_unique(); + meshGroup->GetSceneNodeSelectionList().AddSelectedNode("testMesh"); + scene.GetManifest().AddEntry(AZStd::move(meshGroup)); + + AZ::SceneGenerationComponents::MeshOptimizerComponent component; + AZ::SceneAPI::Events::GenerateSimplificationEventContext context(scene, "pc"); + component.OptimizeMeshes(context); + + AZ::SceneAPI::Containers::SceneGraph::NodeIndex optimizedNodeIndex = graph.Find(AZStd::string("testMesh").append(AZ::SceneAPI::Utilities::OptimizedMeshSuffix)); + ASSERT_TRUE(optimizedNodeIndex.IsValid()) << "Mesh optimizer did not add an optimized version of the mesh"; + + const auto& optimizedMesh = AZStd::rtti_pointer_cast(graph.GetNodeContent(optimizedNodeIndex)); + ASSERT_TRUE(optimizedMesh); + + AZ::SceneAPI::Containers::SceneGraph::NodeIndex optimizedSkinDataNodeIndex = graph.Find(AZStd::string("testMesh").append(AZ::SceneAPI::Utilities::OptimizedMeshSuffix).append(".skinWeights")); + ASSERT_TRUE(optimizedSkinDataNodeIndex.IsValid()) << "Mesh optimizer did not add an optimized version of the skin data"; + + const auto& optimizedSkinWeights = AZStd::rtti_pointer_cast(graph.GetNodeContent(optimizedSkinDataNodeIndex)); + ASSERT_TRUE(optimizedSkinWeights); + + const AZStd::vector> expectedLinks + { + /*0*/ { {0, 0.5f}, {1, 0.5f} }, + /*1*/ { {0, 1.0f} }, + /*2*/ { {0, 0.5f}, {1, 0.5f} }, + /*3*/ { {1, 1.0f} }, + }; + + AZStd::vector> gotLinks(optimizedMesh->GetVertexCount()); + for (unsigned int vertexIndex = 0; vertexIndex < optimizedMesh->GetVertexCount(); ++vertexIndex) + { + for (size_t linkIndex = 0; linkIndex < optimizedSkinWeights->GetLinkCount(vertexIndex); ++linkIndex) + { + gotLinks[vertexIndex].emplace_back(optimizedSkinWeights->GetLink(vertexIndex, linkIndex)); + } + } + EXPECT_THAT(gotLinks, testing::Pointwise(VectorOfVectorOfLinksEq(), expectedLinks)); + } +} // namespace SceneProcessing diff --git a/Gems/SceneProcessing/Code/sceneprocessing_editor_tests_files.cmake b/Gems/SceneProcessing/Code/sceneprocessing_editor_tests_files.cmake index 9ebe2291a3..c06d21233d 100644 --- a/Gems/SceneProcessing/Code/sceneprocessing_editor_tests_files.cmake +++ b/Gems/SceneProcessing/Code/sceneprocessing_editor_tests_files.cmake @@ -7,6 +7,7 @@ set(FILES Tests/InitSceneAPIFixture.h + Tests/MeshBuilder/MeshOptimizerComponentTests.cpp Tests/MeshBuilder/MeshBuilderTests.cpp Tests/MeshBuilder/MeshVerticesTests.cpp Tests/MeshBuilder/SkinInfluencesTests.cpp From 0863a2449086d9ee4a5d7e2ad40dfc2ad348d603 Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Thu, 15 Jul 2021 03:18:10 -0700 Subject: [PATCH 49/53] Revert "[MeshOptimizer] Determine the original vertex index based on the position (#2008)" (#2188) This reverts commit a077a88d3f7b066fd26446b7e6e821f66dcc9b9a due to assets failing on Jenkins. Signed-off-by: Benjamin Jillich --- .../SceneAPI/SceneData/Groups/MeshGroup.h | 24 +- Gems/SceneProcessing/Code/CMakeLists.txt | 1 - .../MeshOptimizer/MeshOptimizerComponent.cpp | 127 ++-------- .../MeshOptimizerComponentTests.cpp | 221 ------------------ .../sceneprocessing_editor_tests_files.cmake | 1 - 5 files changed, 34 insertions(+), 340 deletions(-) delete mode 100644 Gems/SceneProcessing/Code/Tests/MeshBuilder/MeshOptimizerComponentTests.cpp diff --git a/Code/Tools/SceneAPI/SceneData/Groups/MeshGroup.h b/Code/Tools/SceneAPI/SceneData/Groups/MeshGroup.h index 5b4c4612ad..c06c91a808 100644 --- a/Code/Tools/SceneAPI/SceneData/Groups/MeshGroup.h +++ b/Code/Tools/SceneAPI/SceneData/Groups/MeshGroup.h @@ -28,27 +28,27 @@ namespace AZ } namespace SceneData { - class SCENE_DATA_CLASS MeshGroup + class MeshGroup : public DataTypes::IMeshGroup { public: AZ_RTTI(MeshGroup, "{07B356B7-3635-40B5-878A-FAC4EFD5AD86}", DataTypes::IMeshGroup); AZ_CLASS_ALLOCATOR(MeshGroup, SystemAllocator, 0) - SCENE_DATA_API MeshGroup(); - SCENE_DATA_API ~MeshGroup() override = default; + MeshGroup(); + ~MeshGroup() override = default; - SCENE_DATA_API const AZStd::string& GetName() const override; - SCENE_DATA_API void SetName(const AZStd::string& name); - SCENE_DATA_API void SetName(AZStd::string&& name) override; - SCENE_DATA_API const Uuid& GetId() const override; - SCENE_DATA_API void OverrideId(const Uuid& id) override; + const AZStd::string& GetName() const override; + void SetName(const AZStd::string& name); + void SetName(AZStd::string&& name) override; + const Uuid& GetId() const override; + void OverrideId(const Uuid& id) override; - SCENE_DATA_API Containers::RuleContainer& GetRuleContainer() override; - SCENE_DATA_API const Containers::RuleContainer& GetRuleContainerConst() const override; + Containers::RuleContainer& GetRuleContainer() override; + const Containers::RuleContainer& GetRuleContainerConst() const override; - SCENE_DATA_API DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList() override; - SCENE_DATA_API const DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList() const override; + DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList() override; + const DataTypes::ISceneNodeSelectionList& GetSceneNodeSelectionList() const override; static void Reflect(AZ::ReflectContext* context); static bool VersionConverter(SerializeContext& context, SerializeContext::DataElementNode& classElement); diff --git a/Gems/SceneProcessing/Code/CMakeLists.txt b/Gems/SceneProcessing/Code/CMakeLists.txt index 57fc458d70..b33e157e51 100644 --- a/Gems/SceneProcessing/Code/CMakeLists.txt +++ b/Gems/SceneProcessing/Code/CMakeLists.txt @@ -112,7 +112,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) PRIVATE Gem::SceneProcessing.Editor.Static AZ::AzTest - AZ::SceneData ) ly_add_googletest( NAME Gem::SceneProcessing.Editor.Tests diff --git a/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp b/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp index 634dafa99c..e3eb617601 100644 --- a/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp +++ b/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp @@ -96,85 +96,6 @@ namespace AZ::SceneGenerationComponents namespace Containers = AZ::SceneAPI::Containers; namespace Views = Containers::Views; - // @brief A class to map from a mesh's vertex index to it's welded vertex index - // - // When the mesh optimizer runs, it welds nearby vertices (if there are no blendshapes). This class provides a - // constant time lookup to map from an unwelded vertex index to the welded one. - // The welding works by rounding the vertex's position to the given position tolerance, then uses that rounded - // Vector3 as a key into a unordered_map. - template - class Vector3Map - : private AZStd::unordered_map - { - public: - Vector3Map(const MeshDataType* meshData, bool hasBlendShapes, float positionTolerance) - : m_meshData(meshData) - , m_hasBlendShapes(hasBlendShapes) - , m_positionTolerance(positionTolerance) - , m_positionToleranceReciprocal(1.0f / positionTolerance) - { - } - - using AZStd::unordered_map::reserve; - - AZ::u32 operator[](const AZ::u32 vertexIndex) - { - if (m_hasBlendShapes) - { - // Don't attempt to weld similar vertices if there's blendshapes - // Welding the vertices here based on position could cause the vertices of a base shape to be welded, - // and the vertices of the blendshape to not be welded, resulting in a vertex count mismatch between - // the two - return m_meshData->GetUsedPointIndexForControlPoint(m_meshData->GetControlPointIndex(vertexIndex)); - } - - const auto& [iter, didInsert] = try_emplace(GetPositionForIndex(vertexIndex), m_currentOriginalVertexIndex); - if (didInsert) - { - ++m_currentOriginalVertexIndex; - } - return iter->second; - } - - [[nodiscard]] AZ::u32 at(const AZ::u32 vertexIndex) const - { - if (m_hasBlendShapes) - { - // Don't attempt to weld similar vertices if there's blendshapes - // Welding the vertices here based on position could cause the vertices of a base shape to be welded, - // and the vertices of the blendshape to not be welded, resulting in a vertex count mismatch between - // the two - return m_meshData->GetUsedPointIndexForControlPoint(m_meshData->GetControlPointIndex(vertexIndex)); - } - - auto iter = find(GetPositionForIndex(vertexIndex)); - AZSTD_CONTAINER_ASSERT(iter != end(), "Element with key is not present"); - return iter->second; - } - - private: - - AZ::Vector3 GetPositionForIndex(const AZ::u32 vertexIndex) const - { - // Round the vertex position so that a float comparison can be made with entires in the map - // pos = floor( x * 10 + 0.5) * 0.1 - return AZ::Vector3( - AZ::Simd::Vec3::Floor( - (m_meshData->GetPosition(vertexIndex) * m_positionToleranceReciprocal + AZ::Vector3(0.5f)).GetSimdValue() - ) - ) * m_positionTolerance; - } - - const MeshDataType* m_meshData; - bool m_hasBlendShapes; - float m_positionTolerance; - float m_positionToleranceReciprocal; - AZ::u32 m_currentOriginalVertexIndex = 0; - }; - - template - Vector3Map(const MeshDataType*) -> Vector3Map; - MeshOptimizerComponent::MeshOptimizerComponent() { BindToCall(&MeshOptimizerComponent::OptimizeMeshes); @@ -185,7 +106,7 @@ namespace AZ::SceneGenerationComponents auto* serializeContext = azrtti_cast(context); if (serializeContext) { - serializeContext->Class()->Version(4); + serializeContext->Class()->Version(2); } } @@ -194,8 +115,7 @@ namespace AZ::SceneGenerationComponents const MeshDataType* meshData, const SkinWeightDataView& skinWeights, AZ::u32 maxWeightsPerVertex, - float weightThreshold, - const Vector3Map& positionMap) + float weightThreshold) { if (skinWeights.empty()) { @@ -221,12 +141,15 @@ namespace AZ::SceneGenerationComponents for (size_t linkIndex = 0; linkIndex < linkCount; ++linkIndex) { const ISkinWeightData::Link& link = skinData.get().GetLink(controlPointIndex, linkIndex); - skinningInfo->AddInfluence(positionMap.at(usedPointIndex), {aznumeric_caster(link.boneId), link.weight}); + skinningInfo->AddInfluence(usedPointIndex, {aznumeric_caster(link.boneId), link.weight}); } } } - skinningInfo->Optimize(maxWeightsPerVertex, weightThreshold); + if (skinningInfo) + { + skinningInfo->Optimize(maxWeightsPerVertex, weightThreshold); + } return skinningInfo; } @@ -269,12 +192,17 @@ namespace AZ::SceneGenerationComponents const AZStd::vector> meshes = [](const SceneGraph& graph) { AZStd::vector> meshes; - const auto meshNodes = Containers::MakeDerivedFilterView(graph.GetContentStorage()); - for (auto it = meshNodes.cbegin(); it != meshNodes.cend(); ++it) + for (auto it = graph.GetContentStorage().cbegin(); it != graph.GetContentStorage().cend(); ++it) { + // Skip anything that isn't a mesh. + const auto* mesh = azdynamic_cast(it->get()); + if (!mesh) + { + continue; + } + // Get the mesh data and node index and store them in the vector as a pair, so we can iterate over them later. - // The sequential calls to GetBaseIterator unwrap the layers of FilterIterators from the MakeDerivedFilterView - meshes.emplace_back(&(*it), graph.ConvertToNodeIndex(it.GetBaseIterator().GetBaseIterator().GetBaseIterator())); + meshes.emplace_back(mesh, graph.ConvertToNodeIndex(it)); } return meshes; }(graph); @@ -359,12 +287,6 @@ namespace AZ::SceneGenerationComponents auto [optimizedMesh, optimizedUVs, optimizedTangents, optimizedBitangents, optimizedVertexColors, optimizedSkinWeights] = OptimizeMesh(mesh, mesh, uvDatas, tangentDatas, bitangentDatas, colorDatas, skinWeightDatas, meshGroup, hasBlendShapes); - AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Base mesh: %zu vertices, optimized mesh: %zu vertices, %0.02f%% of the original", - mesh->GetUsedControlPointCount(), - optimizedMesh->GetUsedControlPointCount(), - ((float)optimizedMesh->GetUsedControlPointCount() / (float)mesh->GetUsedControlPointCount()) * 100.0f - ); - const NodeIndex optimizedMeshNodeIndex = graph.AddChild(graph.GetNodeParent(nodeIndex), name.c_str(), AZStd::move(optimizedMesh)); auto addOptimizedNodes = [&graph, &optimizedMeshNodeIndex](const auto& originalNodeIndexes, auto& optimizedNodes) @@ -506,9 +428,10 @@ namespace AZ::SceneGenerationComponents const AZStd::vector bitangentLayers = makeLayersForData(bitangents); const AZStd::vector vertexColorLayers = makeLayersForData(vertexColors); - constexpr float positionTolerance = 0.0001f; - Vector3Map positionMap(meshData, hasBlendShapes, positionTolerance); - positionMap.reserve(vertexCount); + const auto* skinRule = meshGroup.GetRuleContainerConst().FindFirstByType().get(); + const AZ::u32 maxWeightsPerVertex = skinRule ? skinRule->GetMaxWeightsPerVertex() : 4; + const float weightThreshold = skinRule ? skinRule->GetWeightThreshold() : 0.001f; + meshBuilder.SetSkinningInfo(ExtractSkinningInfo(meshData, skinWeights, maxWeightsPerVertex, weightThreshold)); // Add the vertex data to all the layers const AZ::u32 faceCount = meshData->GetFaceCount(); @@ -517,8 +440,8 @@ namespace AZ::SceneGenerationComponents meshBuilder.BeginPolygon(baseMesh->GetFaceMaterialId(faceIndex)); for (const AZ::u32 vertexIndex : meshData->GetFaceInfo(faceIndex).vertexIndex) { - const AZ::u32 orgVertexNumber = positionMap[vertexIndex]; - + const int orgVertexNumber = meshData->GetUsedPointIndexForControlPoint(meshData->GetControlPointIndex(vertexIndex)); + AZ_Assert(orgVertexNumber >= 0, "Invalid vertex number"); orgVtxLayer->SetCurrentVertexValue(orgVertexNumber); posLayer->SetCurrentVertexValue(meshData->GetPosition(vertexIndex)); @@ -548,12 +471,6 @@ namespace AZ::SceneGenerationComponents meshBuilder.EndPolygon(); } - - const auto* skinRule = meshGroup.GetRuleContainerConst().FindFirstByType().get(); - const AZ::u32 maxWeightsPerVertex = skinRule ? skinRule->GetMaxWeightsPerVertex() : 4; - const float weightThreshold = skinRule ? skinRule->GetWeightThreshold() : 0.001f; - meshBuilder.SetSkinningInfo(ExtractSkinningInfo(meshData, skinWeights, maxWeightsPerVertex, weightThreshold, positionMap)); - meshBuilder.GenerateSubMeshVertexOrders(); // Create the resulting nodes diff --git a/Gems/SceneProcessing/Code/Tests/MeshBuilder/MeshOptimizerComponentTests.cpp b/Gems/SceneProcessing/Code/Tests/MeshBuilder/MeshOptimizerComponentTests.cpp deleted file mode 100644 index 81528fc3e4..0000000000 --- a/Gems/SceneProcessing/Code/Tests/MeshBuilder/MeshOptimizerComponentTests.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace AZ::SceneAPI::DataTypes -{ - void PrintTo(const ISkinWeightData::Link& link, ::std::ostream* os) - { - *os << '{' << link.boneId << ", " << link.weight << '}'; - } -} - -namespace SceneProcessing -{ - class VertexDeduplicationFixture - : public SceneProcessing::InitSceneAPIFixture - { - public: - void SetUp() override - { - SceneProcessing::InitSceneAPIFixture::SetUp(); - - m_systemEntity = m_app.Create({}, {}); - m_systemEntity->AddComponent(aznew AZ::MemoryComponent()); - m_systemEntity->AddComponent(aznew AZ::JobManagerComponent()); - m_systemEntity->Init(); - m_systemEntity->Activate(); - } - void TearDown() override - { - m_systemEntity->Deactivate(); - SceneProcessing::InitSceneAPIFixture::TearDown(); - } - - static AZStd::unique_ptr MakePlaneMesh() - { - // Create a simple plane with 2 triangles, 6 total vertices, 2 shared vertices - // 0 --- 1 - // | / | - // | / | - // | / | - // 2 --- 3 - const AZStd::array planeVertexPositions = { - AZ::Vector3{0.0f, 0.0f, 0.0f}, - AZ::Vector3{0.0f, 0.0f, 1.0f}, - AZ::Vector3{1.0f, 0.0f, 1.0f}, - AZ::Vector3{1.0f, 0.0f, 1.0f}, - AZ::Vector3{1.0f, 0.0f, 0.0f}, - AZ::Vector3{0.0f, 0.0f, 0.0f}, - }; - - auto mesh = AZStd::make_unique(); - - int i = 0; - for (const AZ::Vector3& position : planeVertexPositions) - { - mesh->AddPosition(position); - mesh->AddNormal(AZ::Vector3::CreateAxisY()); - - // This assumes that the data coming from the import process gives a unique control point - // index to every vertex. This follows the behavior of the AssImp library. - mesh->SetVertexIndexToControlPointIndexMap(i, i); - ++i; - } - - mesh->AddFace({0, 1, 2}, 0); - mesh->AddFace({3, 4, 5}, 0); - - return mesh; - } - - static AZStd::unique_ptr MakeSkinData() - { - auto skinWeights = AZStd::make_unique(); - - skinWeights->ResizeContainerSpace(6); - - // Add bones 0 and 1 to the skin weights - skinWeights->GetBoneId("0"); - skinWeights->GetBoneId("1"); - - skinWeights->AppendLink(0, {/*.boneId=*/0, /*.weight=*/1}); - skinWeights->AppendLink(1, {/*.boneId=*/0, /*.weight=*/1}); - skinWeights->AppendLink(2, {/*.boneId=*/0, /*.weight=*/1}); - skinWeights->AppendLink(3, {/*.boneId=*/1, /*.weight=*/1}); - skinWeights->AppendLink(4, {/*.boneId=*/1, /*.weight=*/1}); - skinWeights->AppendLink(5, {/*.boneId=*/1, /*.weight=*/1}); - - return skinWeights; - } - - private: - AZ::ComponentApplication m_app; - AZ::Entity* m_systemEntity; - }; - - TEST_F(VertexDeduplicationFixture, CanDeduplicateVertices) - { - AZ::SceneAPI::Containers::Scene scene("testScene"); - AZ::SceneAPI::Containers::SceneGraph& graph = scene.GetGraph(); - - const auto meshNodeIndex = graph.AddChild(graph.GetRoot(), "testMesh", MakePlaneMesh()); - - // The original source mesh should have 6 vertices - EXPECT_EQ(AZStd::rtti_pointer_cast(graph.GetNodeContent(meshNodeIndex))->GetVertexCount(), 6); - - auto meshGroup = AZStd::make_unique(); - meshGroup->GetSceneNodeSelectionList().AddSelectedNode("testMesh"); - scene.GetManifest().AddEntry(AZStd::move(meshGroup)); - - AZ::SceneGenerationComponents::MeshOptimizerComponent component; - AZ::SceneAPI::Events::GenerateSimplificationEventContext context(scene, "pc"); - component.OptimizeMeshes(context); - - AZ::SceneAPI::Containers::SceneGraph::NodeIndex optimizedNodeIndex = graph.Find(AZStd::string("testMesh").append(AZ::SceneAPI::Utilities::OptimizedMeshSuffix)); - ASSERT_TRUE(optimizedNodeIndex.IsValid()) << "Mesh optimizer did not add an optimized version of the mesh"; - - const auto& optimizedMesh = AZStd::rtti_pointer_cast(graph.GetNodeContent(optimizedNodeIndex)); - ASSERT_TRUE(optimizedMesh); - - // The optimized mesh should have 4 vertices, the 2 shared vertices are welded together - EXPECT_EQ(optimizedMesh->GetVertexCount(), 4); - } - - MATCHER(VectorOfLinksEq, "") - { - return testing::ExplainMatchResult( - testing::AllOf( - testing::Field(&AZ::SceneData::GraphData::SkinWeightData::Link::boneId, testing::Eq(testing::get<0>(arg).boneId)), - testing::Field(&AZ::SceneData::GraphData::SkinWeightData::Link::weight, testing::FloatEq(testing::get<0>(arg).weight)) - ), - testing::get<1>(arg), - result_listener - ); - } - - MATCHER(VectorOfVectorOfLinksEq, "") - { - return testing::ExplainMatchResult( - testing::UnorderedPointwise(VectorOfLinksEq(), testing::get<0>(arg)), - testing::get<1>(arg), - result_listener - ); - } - - TEST_F(VertexDeduplicationFixture, DeduplicatedVerticesRemapSkinning) - { - AZ::SceneAPI::Containers::Scene scene("testScene"); - AZ::SceneAPI::Containers::SceneGraph& graph = scene.GetGraph(); - - const auto meshNodeIndex = graph.AddChild(graph.GetRoot(), "testMesh", MakePlaneMesh()); - const auto skinDataNodeIndex = graph.AddChild(meshNodeIndex, "skinData", MakeSkinData()); - graph.MakeEndPoint(skinDataNodeIndex); - - // The original source mesh should have 6 vertices - EXPECT_EQ(AZStd::rtti_pointer_cast(graph.GetNodeContent(meshNodeIndex))->GetVertexCount(), 6); - - auto meshGroup = AZStd::make_unique(); - meshGroup->GetSceneNodeSelectionList().AddSelectedNode("testMesh"); - scene.GetManifest().AddEntry(AZStd::move(meshGroup)); - - AZ::SceneGenerationComponents::MeshOptimizerComponent component; - AZ::SceneAPI::Events::GenerateSimplificationEventContext context(scene, "pc"); - component.OptimizeMeshes(context); - - AZ::SceneAPI::Containers::SceneGraph::NodeIndex optimizedNodeIndex = graph.Find(AZStd::string("testMesh").append(AZ::SceneAPI::Utilities::OptimizedMeshSuffix)); - ASSERT_TRUE(optimizedNodeIndex.IsValid()) << "Mesh optimizer did not add an optimized version of the mesh"; - - const auto& optimizedMesh = AZStd::rtti_pointer_cast(graph.GetNodeContent(optimizedNodeIndex)); - ASSERT_TRUE(optimizedMesh); - - AZ::SceneAPI::Containers::SceneGraph::NodeIndex optimizedSkinDataNodeIndex = graph.Find(AZStd::string("testMesh").append(AZ::SceneAPI::Utilities::OptimizedMeshSuffix).append(".skinWeights")); - ASSERT_TRUE(optimizedSkinDataNodeIndex.IsValid()) << "Mesh optimizer did not add an optimized version of the skin data"; - - const auto& optimizedSkinWeights = AZStd::rtti_pointer_cast(graph.GetNodeContent(optimizedSkinDataNodeIndex)); - ASSERT_TRUE(optimizedSkinWeights); - - const AZStd::vector> expectedLinks - { - /*0*/ { {0, 0.5f}, {1, 0.5f} }, - /*1*/ { {0, 1.0f} }, - /*2*/ { {0, 0.5f}, {1, 0.5f} }, - /*3*/ { {1, 1.0f} }, - }; - - AZStd::vector> gotLinks(optimizedMesh->GetVertexCount()); - for (unsigned int vertexIndex = 0; vertexIndex < optimizedMesh->GetVertexCount(); ++vertexIndex) - { - for (size_t linkIndex = 0; linkIndex < optimizedSkinWeights->GetLinkCount(vertexIndex); ++linkIndex) - { - gotLinks[vertexIndex].emplace_back(optimizedSkinWeights->GetLink(vertexIndex, linkIndex)); - } - } - EXPECT_THAT(gotLinks, testing::Pointwise(VectorOfVectorOfLinksEq(), expectedLinks)); - } -} // namespace SceneProcessing diff --git a/Gems/SceneProcessing/Code/sceneprocessing_editor_tests_files.cmake b/Gems/SceneProcessing/Code/sceneprocessing_editor_tests_files.cmake index c06d21233d..9ebe2291a3 100644 --- a/Gems/SceneProcessing/Code/sceneprocessing_editor_tests_files.cmake +++ b/Gems/SceneProcessing/Code/sceneprocessing_editor_tests_files.cmake @@ -7,7 +7,6 @@ set(FILES Tests/InitSceneAPIFixture.h - Tests/MeshBuilder/MeshOptimizerComponentTests.cpp Tests/MeshBuilder/MeshBuilderTests.cpp Tests/MeshBuilder/MeshVerticesTests.cpp Tests/MeshBuilder/SkinInfluencesTests.cpp From 4aebea61af8f1dda209b915a48739a1c98cad4e4 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Thu, 15 Jul 2021 09:42:02 -0700 Subject: [PATCH 50/53] Fixes for Jenkins Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- .../AzToolsFramework/Tests/ArchiveTests.cpp | 12 +++++++++ .../Tests/AssetSeedManager.cpp | 26 +++++++++---------- .../AzToolsFramework/Tests/FileFunc.cpp | 2 ++ 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/Code/Framework/AzToolsFramework/Tests/ArchiveTests.cpp b/Code/Framework/AzToolsFramework/Tests/ArchiveTests.cpp index 3b08e04304..71b86f6ef4 100644 --- a/Code/Framework/AzToolsFramework/Tests/ArchiveTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/ArchiveTests.cpp @@ -130,7 +130,11 @@ namespace UnitTest UnitTest::ScopedTemporaryDirectory m_tempDir; }; +#if AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS + TEST_F(ArchiveTest, DISABLED_CreateArchiveBlocking_FilesAtThreeDepths_ArchiveCreated) +#else TEST_F(ArchiveTest, CreateArchiveBlocking_FilesAtThreeDepths_ArchiveCreated) +#endif // AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS { EXPECT_TRUE(m_tempDir.IsValid()); CreateArchiveFolder(); @@ -140,7 +144,11 @@ namespace UnitTest EXPECT_EQ(createResult, true); } +#if AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS + TEST_F(ArchiveTest, DISABLED_ListFilesInArchiveBlocking_FilesAtThreeDepths_FilesFound) +#else TEST_F(ArchiveTest, ListFilesInArchiveBlocking_FilesAtThreeDepths_FilesFound) +#endif // AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS { EXPECT_TRUE(m_tempDir.IsValid()); CreateArchiveFolder(); @@ -154,7 +162,11 @@ namespace UnitTest EXPECT_EQ(fileList.size(), 6); } +#if AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS + TEST_F(ArchiveTest, DISABLED_CreateDeltaCatalog_AssetsNotRegistered_Failure) +#else TEST_F(ArchiveTest, CreateDeltaCatalog_AssetsNotRegistered_Failure) +#endif // AZ_TRAIT_DISABLE_FAILED_ARCHIVE_TESTS { QStringList fileList = CreateArchiveFileList(); diff --git a/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp b/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp index 9ac53e4702..dafd2faa4a 100644 --- a/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp +++ b/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp @@ -92,7 +92,7 @@ namespace UnitTest { m_fileStreams[platformCount][idx].Write(m_assetsPath[idx].size(), m_assetsPath[idx].data()); m_fileStreams[platformCount][idx].Close(); - AZ_TEST_STOP_TRACE_SUPPRESSION(thisPlatform == AzFramework::PlatformId::PC ? 1 : 0); // writing to asset cache folder, only invalid for PC + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, only invalid for PC, not invalid in Jenkins } else { @@ -116,7 +116,7 @@ namespace UnitTest AZ_TEST_START_TRACE_SUPPRESSION; AZ::IO::FileIOStream dynamicSliceFileIOStream(TestDynamicSliceAssetPath, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins AZ::Data::AssetInfo sliceAssetInfo; sliceAssetInfo.m_relativePath = TestSliceAssetPath; @@ -130,7 +130,7 @@ namespace UnitTest AZ_TEST_START_TRACE_SUPPRESSION; AZ::IO::FileIOStream sliceFileIOStream(TestSliceAssetPath, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins // asset0 -> asset1 -> asset2 -> asset4 // --> asset3 @@ -202,7 +202,7 @@ namespace UnitTest { AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(s_catalogFile); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins } for (size_t platformCount = 0; platformCount < s_totalTestPlatforms; ++platformCount) @@ -215,7 +215,7 @@ namespace UnitTest { AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(m_assetsPathFull[platformCount][idx].c_str()); - AZ_TEST_STOP_TRACE_SUPPRESSION(platformCount == 0 ? 1 : 0); // deleting from asset cache folder + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins } } } @@ -224,14 +224,14 @@ namespace UnitTest { AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(TestSliceAssetPath); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins } if (fileIO->Exists(TestDynamicSliceAssetPath)) { AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(TestDynamicSliceAssetPath); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins } auto pcCatalogFile = AzToolsFramework::PlatformAddressedAssetCatalog::GetCatalogRegistryPathForPlatform(AzFramework::PlatformId::PC); @@ -240,7 +240,7 @@ namespace UnitTest { AZ_TEST_START_TRACE_SUPPRESSION; fileIO->Remove(pcCatalogFile.c_str()); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins } if (fileIO->Exists(androidCatalogFile.c_str())) @@ -283,7 +283,7 @@ namespace UnitTest // Attempt to save to the same file. Should not be allowed. AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_FALSE(m_assetSeedManager->Save(filePath)); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins // Clean up the test environment AZ::IO::SystemFile::SetWritable(filePath.c_str(), true); @@ -309,7 +309,7 @@ namespace UnitTest // Attempt to save to the same file. Should not be allowed. AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_FALSE(m_assetSeedManager->SaveAssetFileInfo(filePath, AzFramework::PlatformFlags::Platform_PC, {})); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins // Clean up the test environment AZ::IO::SystemFile::SetWritable(filePath.c_str(), true); @@ -378,7 +378,7 @@ namespace UnitTest // Step we are testing AZ_TEST_START_TRACE_SUPPRESSION; m_assetSeedManager->AddPlatformToAllSeeds(AzFramework::PlatformId::ANDROID_ID); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins // Verification AzFramework::PlatformFlags expectedPlatformFlags = AzFramework::PlatformFlags::Platform_PC | AzFramework::PlatformFlags::Platform_ANDROID; @@ -650,7 +650,7 @@ namespace UnitTest AZStd::string fileContent = AZStd::string::format("asset%d.txt", fileIndex); m_fileStreams[0][fileIndex].Write(fileContent.size(), fileContent.c_str()); m_fileStreams[0][fileIndex].Close(); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins } AzToolsFramework::AssetFileInfoList assetList2 = m_assetSeedManager->GetDependencyList(AzFramework::PlatformId::PC); @@ -683,7 +683,7 @@ namespace UnitTest AZStd::string fileContent = AZStd::string::format("asset%d.txt", fileIndex + 1);// changing file content m_fileStreams[0][fileIndex].Write(fileContent.size(), fileContent.c_str()); m_fileStreams[0][fileIndex].Close(); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins } AzToolsFramework::AssetFileInfoList assetList2 = m_assetSeedManager->GetDependencyList(AzFramework::PlatformId::PC); diff --git a/Code/Framework/AzToolsFramework/Tests/FileFunc.cpp b/Code/Framework/AzToolsFramework/Tests/FileFunc.cpp index 420caa0f55..124e9af0f2 100644 --- a/Code/Framework/AzToolsFramework/Tests/FileFunc.cpp +++ b/Code/Framework/AzToolsFramework/Tests/FileFunc.cpp @@ -47,11 +47,13 @@ namespace UnitTest void SetUp() { m_prevFileIO = AZ::IO::FileIOBase::GetInstance(); + AZ::IO::FileIOBase::SetInstance(nullptr); AZ::IO::FileIOBase::SetInstance(&m_fileIO); } void TearDown() override { + AZ::IO::FileIOBase::SetInstance(nullptr); AZ::IO::FileIOBase::SetInstance(m_prevFileIO); } From 087c9f6edb4c1f26617874e67a87dc77f20a9d3b Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Thu, 15 Jul 2021 11:40:34 -0700 Subject: [PATCH 51/53] more fixes for Jenkins vs local behavior Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- .../AzToolsFramework/Tests/Prefab/PrefabLoadTemplateTests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabLoadTemplateTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabLoadTemplateTests.cpp index bf47e57206..a3d6cafd2a 100644 --- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabLoadTemplateTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabLoadTemplateTests.cpp @@ -336,7 +336,7 @@ namespace UnitTest templateData.m_id = m_prefabLoaderInterface->LoadTemplateFromString( selfDependentPrefabStr, templateData.m_filePath); - AZ_TEST_STOP_TRACE_SUPPRESSION(3); + AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // produces different counts in Jenkins vs local templateData.m_isLoadedWithErrors = true; From 7ef383580e486a93df633482e7ec6275c7fb7e9e Mon Sep 17 00:00:00 2001 From: moudgils <47460854+moudgils@users.noreply.github.com> Date: Thu, 15 Jul 2021 11:50:19 -0700 Subject: [PATCH 52/53] Metal sync interval support (#2187) * Metal sync interval support Add shader name to SRGPool for debugging purposes Set default value of rpi_vsync_interval to 1 Signed-off-by: moudgils --- .../Source/Platform/Mac/RHI/Metal_RHI_Mac.cpp | 31 +++++++++++++++++-- .../Source/Platform/iOS/RHI/Metal_RHI_iOS.cpp | 16 +++++++--- .../RHI/Metal/Code/Source/RHI/SwapChain.cpp | 17 +++++++--- .../RHI/Metal/Code/Source/RHI/SwapChain.h | 1 + .../Shader/ShaderResourceGroupPool.cpp | 4 +-- .../Code/Source/RPI.Public/WindowContext.cpp | 2 +- 6 files changed, 56 insertions(+), 15 deletions(-) diff --git a/Gems/Atom/RHI/Metal/Code/Source/Platform/Mac/RHI/Metal_RHI_Mac.cpp b/Gems/Atom/RHI/Metal/Code/Source/Platform/Mac/RHI/Metal_RHI_Mac.cpp index de3bc23a11..cb9e72118a 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/Platform/Mac/RHI/Metal_RHI_Mac.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/Platform/Mac/RHI/Metal_RHI_Mac.cpp @@ -43,11 +43,36 @@ namespace Platform } return physicalDeviceList; } + + float GetRefreshRate() + { + CGDirectDisplayID display = CGMainDisplayID(); + CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(display); + return CGDisplayModeGetRefreshRate(currentMode); + } - void PresentInternal(id mtlCommandBuffer, id drawable, float syncInterval) + void PresentInternal(id mtlCommandBuffer, id drawable, float syncInterval, float refreshRate) { - AZ_UNUSED(syncInterval); - [mtlCommandBuffer presentDrawable:drawable]; + bool framePresented = false; + + //seconds per frame (1/refreshrate) * num frames (sync interval) + float presentAfterMinimumDuration = syncInterval / refreshRate; + +#if defined(__MAC_10_15_4) + if(@available(macOS 10.15.4, *)) + { + if(presentAfterMinimumDuration > 0.0f) + { + [mtlCommandBuffer presentDrawable:drawable afterMinimumDuration:presentAfterMinimumDuration]; + framePresented = true; + } + } +#endif + + if(!framePresented) + { + [mtlCommandBuffer presentDrawable:drawable]; + } } CGRect GetScreenBounds(NativeWindowType* nativeWindow) diff --git a/Gems/Atom/RHI/Metal/Code/Source/Platform/iOS/RHI/Metal_RHI_iOS.cpp b/Gems/Atom/RHI/Metal/Code/Source/Platform/iOS/RHI/Metal_RHI_iOS.cpp index b7c309fba2..007655a93e 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/Platform/iOS/RHI/Metal_RHI_iOS.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/Platform/iOS/RHI/Metal_RHI_iOS.cpp @@ -29,13 +29,19 @@ namespace Platform return physicalDeviceList; } - void PresentInternal(id mtlCommandBuffer, id drawable, float syncInterval) + float GetRefreshRate() { - bool hasPresentAfterMinimumDuration = [drawable respondsToSelector:@selector(presentAfterMinimumDuration:)]; - - if (hasPresentAfterMinimumDuration && syncInterval > 0.0f) + NativeScreenType* nativeScreen = [NativeScreenType mainScreen]; + return [nativeScreen maximumFramesPerSecond]; + } + + void PresentInternal(id mtlCommandBuffer, id drawable, float syncInterval, float refreshRate) + { + //seconds per frame (1/refreshrate) * num frames (sync interval) + float presentAfterMinimumDuration = syncInterval / refreshRate; + if (hasPresentAfterMinimumDuration > 0.0f) { - [mtlCommandBuffer presentDrawable:drawable afterMinimumDuration:syncInterval]; + [mtlCommandBuffer presentDrawable:drawable afterMinimumDuration:presentAfterMinimumDuration]; } else { diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.cpp index 31d23e5100..08d5d2be87 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.cpp +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.cpp @@ -19,8 +19,9 @@ namespace Platform CGFloat GetScreenScale(); void AttachViewController(NativeWindowType* nativeWindow, NativeViewControllerType* viewController, RHIMetalView* metalView); void UnAttachViewController(NativeWindowType* nativeWindow, NativeViewControllerType* viewController); - void PresentInternal(id mtlCommandBuffer, id drawable, float syncInterval); + void PresentInternal(id mtlCommandBuffer, id drawable, float syncInterval, float refreshRate); void ResizeInternal(RHIMetalView* metalView, CGSize viewSize); + float GetRefreshRate(); RHIMetalView* GetMetalView(NativeWindowType* nativeWindow); } @@ -73,6 +74,15 @@ namespace AZ AddSubView(); } + m_refreshRate = Platform::GetRefreshRate(); + + //Assume 60hz if 0 is returned. + //Internal OSX displays have 'flexible' refresh rates, with a max of 60Hz - but report 0hz + if (m_refreshRate < 0.1f) + { + m_refreshRate = 60.0f; + } + m_drawables.resize(descriptor.m_dimensions.m_imageCount); if (nativeDimensions) @@ -148,10 +158,9 @@ namespace AZ uint32_t SwapChain::PresentInternal() { const uint32_t currentImageIndex = GetCurrentImageIndex(); - //GFX TODO][ATOM-432] - Hardcoding to 30fps for now. Only used by ios. This needs to be driven by higher level code. - float syncInterval = 1.0f/30.0f; + //Preset the drawable - Platform::PresentInternal(m_mtlCommandBuffer, m_drawables[currentImageIndex], syncInterval); + Platform::PresentInternal(m_mtlCommandBuffer, m_drawables[currentImageIndex], GetDescriptor().m_verticalSyncInterval, m_refreshRate); [m_drawables[currentImageIndex] release]; m_drawables[currentImageIndex] = nil; diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.h b/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.h index c86bd1f7a5..72014005ac 100644 --- a/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.h +++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.h @@ -52,6 +52,7 @@ namespace AZ id m_mtlDevice = nil; NativeWindowType* m_nativeWindow = nullptr; AZStd::vector> m_drawables; + float m_refreshRate = 0.0f; }; } } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderResourceGroupPool.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderResourceGroupPool.cpp index d8c69cf8a0..4e858e4880 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderResourceGroupPool.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/ShaderResourceGroupPool.cpp @@ -58,8 +58,8 @@ namespace AZ RHI::ShaderResourceGroupPoolDescriptor poolDescriptor; poolDescriptor.m_layout = shaderAsset.FindShaderResourceGroupLayout(srgName, supervariantIndex).get(); - - m_pool->SetName(srgName); + m_pool->SetName(AZ::Name(AZStd::string::format("%s_%s",shaderAsset.GetName().GetCStr(),srgName.GetCStr()))); + const RHI::ResultCode resultCode = m_pool->Init(*device, poolDescriptor); return resultCode; } diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/WindowContext.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/WindowContext.cpp index 16ad7a1155..4b8c061b68 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/WindowContext.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/WindowContext.cpp @@ -27,7 +27,7 @@ void OnVsyncIntervalChanged(uint32_t const& interval) // NOTE: On change, broadcasts the new requested vsync interval to all windows. // The value of the vsync interval is constrained between 0 and 4 // Vsync intervals greater than 1 are not currently supported on the Vulkan RHI (see #2061 for discussion) -AZ_CVAR(uint32_t, rpi_vsync_interval, 0, OnVsyncIntervalChanged, AZ::ConsoleFunctorFlags::Null, "Set swapchain vsync interval"); +AZ_CVAR(uint32_t, rpi_vsync_interval, 1, OnVsyncIntervalChanged, AZ::ConsoleFunctorFlags::Null, "Set swapchain vsync interval"); namespace AZ { From 900b82cb361dc998d4f8d7afb192ab24745ec11b Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Thu, 15 Jul 2021 13:40:22 -0700 Subject: [PATCH 53/53] missing dependencies Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt index 73af69b93a..17202acc29 100644 --- a/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt @@ -5,6 +5,13 @@ # if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) + + include(${LY_ROOT_FOLDER}/Code/Tools/SerializeContextTools/Platform/${PAL_PLATFORM_NAME}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) + if (PAL_TRAIT_BUILD_SERIALIZECONTEXTTOOLS) + list(APPEND additional_dependencies AZ::SerializeContextTools) # test_CLITool_SerializeContextTools depends on it + endif() + list(APPEND additional_dependencies AZ::AssetBundlerBatch) # test_CLITool_AssetBundlerBatch_Works depends on it + ly_add_pytest( NAME AutomatedTesting::SmokeTest TEST_SUITE smoke @@ -18,6 +25,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) Legacy::Editor AutomatedTesting.GameLauncher AutomatedTesting.Assets + ${aditional_dependencies} COMPONENT Smoke )